in trying to create a function in c which can get to a specific line in a CSV file (similar to getline()). I'm only allowed to use the ANSI 89/99 standard. Here is what i have wrote so far:
char * getline(FILE * fi,size_t line_length,size_t line_number)
{
size_t i;
char * aux_string;
char * p;
if (fi==NULL)
return NULL;
if ((aux_string = malloc(line_length*sizeof(char)))==NULL)
return NULL;
i=0;
while(fgets(aux_string,line_length,fi)!=NULL||feof(fi)!=0)
{
if (i==line_number)
{
if ((p=strchr(aux_string,'\n'))!=NULL)
{
*p='\0';
}
return aux_string;
}
i++;
}
return NULL;
}
This works fairly ok for a single call to getline(). However, if the function is called like in the example below:
puts(getline(file_a,MAX_LENGTH,0));
puts(getline(file_a,MAX_LENGTH,0));
It outputs the line in the file immediately below, as well as the desired line. How can I avoid this? What could be causing this? Thanks.
FILE*
remembers position inside the file where you ended. So the second time you call fread
the file has already read the first line, so you start reading from the second line. You need to fseek(fi, 0, SEEK_SET)
rewind the file to the beginning.
char * getline(FILE * fi,size_t line_length,size_t line_number)
{
if (fseek(fi, 0, SEEK_SET) != 0) {
// handle error
}
// rest of your function
Notes:
fseek(.., 0, SEEK_SET)
, but offers no error handling (weii, except ferror
that is).puts(getline(file_a,MAX_LENGTH,0));
leaks memory allocated inside getline
. You should char *pnt = getline(...); puts(pnt); free(pnt)
always remember to pick out the trash.feof(fi)!=0
condition from inside the while
loop looks redundant. If the file has no more lines, the fgets
will tell you about it.mygetline
or such, not to confuse others. The function getline
is already a POSIX function that's been around for very long.