Eyzuky Eyzuky - 3 months ago 10
C Question

Printing struct field prints only the last element multiple times - C

I have a struct:

typedef struct fileRep
{
char *fileName;

int index;
int visited;
} fileRep;


My main function has this call to a function that creates an array of struct filRep:

fileRep *allFiles = (fileRep*)malloc(MAX_LINES*sizeof(fileRep));
int i = linesToStruct(allFiles, fp);


This is the function:

int linesToStruct(fileRep* allFiles, FILE* fp)
{
char line[MAX_CHARS_LINE];
int i = 0;
while(fgets(line, sizeof line, fp))
{

fileRep file1 = createBasicFileStruct(line, i);
allFiles[i] = file1;
printf("%s is added\n", allFiles[i]);
i++;
}
return i;
}


which calls this function:

fileRep createBasicFileStruct(char *line, int lineNumber)
{
char* name;
fileRep file1;
name = strtok(line, ":" );
file1.fileName = name;
file1.index = lineNumber;
file1.visited = 0;
return file1;
}


Now i try to iterate and print the fileName field of each fileRep struct i created:

int k = 0;
for(; k < i; k++)
{
printf("File %d is %s\n", k, allFiles[k].fileName);
}


This results in this printing:

File 0 is file4
File 1 is file4
File 2 is file4
File 3 is file4


Now just some more info: The function lineToStruct has an internal test print, which prints:

file1.h is added
file2.h is added
file3.h is added
file4.h is added


Meaning it does add the files.

I am new to C and i am having trouble getting the pointer and array correlation,
Why allFiles[0] is NULL? How do i set it to iterate properly?

Answer
fileRep createBasicFileStruct(char *line, int lineNumber)
{
    char* name;

    fileRep file1;
    name = strtok(line, ":" );
    file1.fileName = name;
    file1.index = lineNumber;
    file1.visited = 0;
    return file1;
}

file1.fileName: the contents of line are replaced on each iteration of fgets in the function linesToStruct, you need to pass strdup(line) instead of line. Don't forget to free all those strings at the end.