I have a text file like this:
123-55555-1 10000 0
123-55533-3 12300 500
123-99971-3 50000 0
123-38951-2 350 10
120-39888-0 4910 100
121-12345-3 50000 150
121-xptoz-3 1000 100
150-23857-1 350000 20000
521-71750-4 500000 25000
191-11999-7 1200
and what I want is to be able to retrieve this information line by line using fgets()
. when I read it I want to call another function that uses the line read works the information and put it on a list. The thing is when I try to call in the function and passing the string as an argument it gives me seg error:11. Here is my code.
typedef struct identificador_s
{
int a;
int b;
int c;
} identificador;
typedef struct contaBancaria_s
{
identificador id;
int saldo;
unsigned short int credito;
struct contaBancaria_s * proximo;
} contaBancaria;
contaBancaria * contaP = NULL;
char contas[] = "contas.txt";
char movimentos[] = "movimentos.txt";
char divideString(char line[], int contagem, char parametro[])
{
int i = 0;
char *a = NULL;
char string1;
a = strtok(line, parametro);
while (i != contagem)
{
a = strtok(NULL, parametro);
i++;
}
string1 = (char) *a;
return string1;
}
void contaFill(char line[])
{
printf("passo -2");
contaBancaria * p = malloc(sizeof(contaBancaria));
printf("passo 0");
int i = 0;
char parametro1[] = "-";
char parametro2[] = " ";
p->id.a = (int) divideString(line, i, parametro1);
printf("passo 1");
p->id.b = (int) divideString(line, i += 1, parametro1);
printf("passo2");
p->id.c = (int) divideString(line, i += 1, parametro1);
printf("passo 3");
/*if(!(validaIdentificador(p-id.a,p->id.b,p-id.c))){
return;
}*/
p->saldo = (int) divideString(line, i += 1, parametro2);
printf("passo 4");
p->credito = (int) divideString(line, i += 1, parametro2);
printf("passo 5");
printf("%d - %d - %d %d %d", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
}
void loadFile(char fileType[])
{
FILE * fp;
fp = fopen(fileType, "r");
int size = 100;
char buffer[100];
char string1[100];
if (fp)
{
while (fgets(buffer, 100, fp) != NULL)
{
puts(buffer);
if (strcmp(fileType, "contas.txt") == 0)
{
contaFill(buffer);
}
}
fclose(fp);
}
}
int main(int argc, char* argv[])
{
loadFile(contas);
return 0;
}
first call divideString(line, i, parametro1);
p->id.a = (int) divideString(line, i, parametro1);
return value is '1' -> 49
first '-'
of line
replace '\0'
by strtok
(E.g. "123-55555-1 10000 0"
-> "123\055555-1 10000 0"
meant "123"
second call divideString(line, i += 1, parametro1);
a = strtok(line, parametro);//not find parametro return `a=line`(top)
...
a = strtok(NULL, parametro);//a=`NULL`
...
string1 = (char) *a;//*(NULL) seg fault!!
to update
The set together and cease to call(divideString
) every member of one.
E.g.
void stringToContaBancaria(char line[], contaBancaria *p, char para1[], char para2[]){
char *a, *endp;
//To convert to int from numeric strings for example it use strtol
p->id.a = strtol(a=strtok(line, para1), &endp, 10);
if(*endp) fprintf(stderr, "id.a not number : %s\n", a);
p->id.b = strtol(a=strtok(NULL, para1), &endp, 10);
if(*endp) fprintf(stderr, "id.b not number : %s\n", a);
p->id.c = strtol(a=strtok(NULL, para2), &endp, 10);
if(*endp) fprintf(stderr, "id.c not number : %s\n", a);
p->saldo = strtol(a=strtok(NULL, para2), &endp, 10);
if(*endp) fprintf(stderr, "saldo not number : %s\n", a);
p->credito = strtoul(a=strtok(NULL, para2), &endp, 10);
if(*endp) fprintf(stderr, "credito not number : %s\n", a);
}
void contaFill(char line[]){
contaBancaria * p = malloc(sizeof(contaBancaria));
char parametro1[] = "-";
char parametro2[] = " ";//" \n"?
stringToContaBancaria(line, p, parametro1, parametro2);
printf("%d - %d - %d %d %hu\n", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
//free(p);//deallocate!
}
it gives me seg error
//less a(=strtok return value) becomes to NULL element when reading is less than expected.
p->credito = strtoul(a=strtok(NULL, para2), &endp, 10);
if(*endp) fprintf(stderr, "credito not number : %s\n", a);
E.g. change to
if(NULL!=(a=strtok(NULL, para2))){
p->credito = strtoul(a, &endp, 10);
if(*endp)fprintf(stderr, "credito not number : %s\n", a);
} else
fprintf(stderr, "credito not exist\n");
but I think the check for the before time rather than do between the reading these necessary items whether there is.
make a simple pre-check
#include <ctype.h>
int isInvalidRecord(char line[]){
//[number]-[number]-[number][space][number][space][number][space*]
//521-71750-4 500000 25000[newline]
int i=0, j;
while(isdigit(line[i]))++i;
if(i==0 || line[i]!='-') return 1;//1st item bad
j=++i;
while(isdigit(line[i]))++i;
if(i==j || line[i]!='-') return 2;
j=++i;
while(isdigit(line[i]))++i;
if(i==j || line[i]!=' ') return 3;
j=++i;
while(isdigit(line[i]))++i;
if(i==j || line[i]!=' ') return 4;
j=++i;
while(isdigit(line[i]))++i;
if(i==j || (line[i]!='\0' && !isspace(line[i]))) return 5;
return 0;//ALL OK
}
void contaFill(char line[]){
contaBancaria * p = malloc(sizeof(contaBancaria));
char parametro1[] = "-";
char parametro2[] = " ";//" \n"?
int check = isInvalidRecord(line);
if(check == 0)//0 is OK
stringToContaBancaria(line, p, parametro1, parametro2);
else
fprintf(stderr, "%s %d item(near) is bad\n", line, check);
printf("%d - %d - %d %d %hu\n", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
//free(p);//deallocate!
}