尝试在c中创建一个函数,该函数可以到达CSV文件中的特定行(类似于getline())。我只允许使用ANSI 89/99标准。这是我到目前为止写的:
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;
}
这对于单次调用getline()来说还是可以的。但是,如果像下面的示例那样调用该函数:
puts(getline(file_a,MAX_LENGTH,0));
puts(getline(file_a,MAX_LENGTH,0));
它将在下面的文件中输出该行以及所需的行。 如何避免这种情况?是什么原因造成的?谢谢。
答案 0 :(得分:2)
FILE*
会记住文件结尾的位置。因此,第二次调用fread
时,文件已经读取了第一行,因此您从第二行开始读取。您需要fseek(fi, 0, SEEK_SET)
将文件倒带到开头。
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
注意:
fseek(.., 0, SEEK_SET)
等效,但是不提供错误处理(唯独ferror
除外)。puts(getline(file_a,MAX_LENGTH,0));
泄漏了getline
内部分配的内存。您应该char *pnt = getline(...); puts(pnt); free(pnt)
永远记得捡垃圾。feof(fi)!=0
循环内部的while
条件看起来很多余。如果文件中没有更多行,则fgets
会告诉您。mygetline
,以免混淆其他函数。函数getline
已经是一个POSIX function,已经存在了很长时间。