使用ANSI函数到达文本文件的特定行

时间:2019-05-26 20:59:00

标签: c csv crud fgets ansi

尝试在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));

它将在下面的文件中输出该行以及所需的行。 如何避免这种情况?是什么原因造成的?谢谢。

1 个答案:

答案 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 

注意:

  • rewindfseek(.., 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,已经存在了很长时间。