0

i have to fill my record with input by file. The record has 4 field, but the problems come out witj the string only. i use strtok to divide mi string into 4 parts but only the string seems like every cells of the array point to the last call of strtok, example and code below:

 int GetRecord(char* file_name,Record* A){
    FILE *fd = fopen(file_name,"rt");int i=0;
    char* st=(char*)malloc(100*sizeof(char*));
    if(fd == NULL){
      printf("GetRecord:path file doesn't exist");
      exit(EXIT_FAILURE);
    };
    
     while(!feof(fd)){
        fscanf(fd,"%s\n",st);
        A[i].id=atoi(strtok(st, ";"));
        A[i].field1 =strtok(NULL, ";");printf("\nString: %s",A[i].field1);
        A[i].field2 = atoi(strtok(NULL, ";"));
        A[i].field3 = atof(strtok(NULL, ";"));
        i++;     
    }
    fclose(fd);
    return i; 
}

int main(int argc,char* argv[]){
    
    OrderedArray* b = ordered_array_create();
    Record* A = (Record*)malloc(START_CAPACITY_RECORD*sizeof(Record));
    
    int dim = GetRecord("TEST.csv",A);
    Record *B;
    for(int i = 0; i<dim;i++){
      ordered_array_add(b,&A[i]);
      B=(Record*)ordered_array_get(b,i);
      printf("\nValore %d field1 %s field2 %i field3 %f position %d",A[i].id,A[i].field1,A[i].field2,A[i].field3,i);
    }
    ordered_array_free(b);
    free(A);
}

My file:

15;Matteo;21;79.7;
14;Serena;20;60.5;

The Output:

String: Matteo
String: Serena
Valore 15 field1 Serena field2 21 field3 79.699997 position 0
Valore 14 field1 Serena field2 20 field3 60.500000 position 1
  • 1
    `strtok` does not make a copy so you are always getting a pointer to `st` or some address inside `st`. You need to make a copy with `strdup` or something similar. – 001 Jun 04 '21 at 23:37
  • temp = strtok(NULL, ";"); strcpy(A[i].field1 ,temp); i tried to use a string temp, but the program crash – Matteo Pagliarello Jun 04 '21 at 23:43
  • A temp string won't work either as it will go out of scope when the function ends. What is `A.field1` - a `char *` or `char []`? – 001 Jun 04 '21 at 23:46
  • thank,work correctly. Last thing ,what is the difference between strdup and strcpy, because i read that strdup is dangerous to use. – Matteo Pagliarello Jun 04 '21 at 23:49
  • You would use `strdup` if the field is a `char *` and use `strcpy` for a `char []`. Note that `strcpy` can be dangerous as it will happily overrun the buffer if the string is too long. There are "safe" versions you can use. – 001 Jun 04 '21 at 23:51
  • Off-topic: `while(feof(...))` is wrong usage. `feof` does **not** know about file end **until** you have done some read operations, so at very least you should change to a do - while loop. See [this question](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – Aconcagua Jun 05 '21 at 00:31
  • You have a memory leak due to `malloc`ing without `free`ing again. You avoid manual memory management if you have the array on the stack: `char st[128];` (cannot fail either, so no `if` necessary; prefer powers of 2 as array size). Still you need *copies* as mentioned already. I'd prefer such an array within `A` struct as well. Solely you need to care about not exceeding this array, but maximum name length is limited anyway due to limited line buffer length... – Aconcagua Jun 05 '21 at 00:35

0 Answers0