【问题标题】:Read the next line of a file every time a function is called每次调用函数时读取文件的下一行
【发布时间】:2014-10-08 22:24:24
【问题描述】:

我有一个文本文件,每行都有数字。我想在 C 中编写一个函数,该函数读取文件并在每次调用该函数时返回文件中的下一个数字。

例如,如果我有这些数字:

100 
200 
300 
400

还有一个叫做get_number()的函数,如果我调用get_number()它会返回100,如果我再次调用它会返回200,等等。

这是我到目前为止所写的,但每次调用该函数时,它总是返回到文本文件中的第一个数字。

int * get_number()
{

    FILE* file = fopen("random_numbers.txt", "r");
    char line[256];

    if (file==NULL) 
    {
        perror ("Error reading file");
    }
    else
    {
        fgets(line, sizeof(line), file);
        printf("%s", line);
    }

    return 0;
}

【问题讨论】:

  • 您需要在读取后使用ftell() 获取文件中的当前位置,并且您需要在每次后续读取之前使用fseek() 查找该位置。跨度>
  • 您在这里泄漏了文件描述符。至少可以这么说。
  • 每次调用该函数时,您都在重新打开文件。尝试在方法之外执行一次,或者在打开文件之前检查该文件是否为 NULL。

标签: c file-io


【解决方案1】:

这里有一个版本可以做到这一点:

 int * get_number(long* pos)
{

    FILE* file = fopen("random_numbers.txt", "r");
    char line[256];

    if (file==NULL) 
    {
        perror ("Error reading file");
    }
    else
    {
        fseek(file , *pos , SEEK_CUR);
        fgets(line, sizeof(line), file);
        printf("%s", line);
    }
    *pos = ftell(file);
    return 0;
}

然后你像这样从main 调用它

long pos = 0;
get_number(&pos);

或者更好的是使用静态变量

 int * get_number()
{
    static long pos = 0;
    FILE* file = fopen("random_numbers.txt", "r");
    char line[256];

    if (file==NULL) 
    {
        perror ("Error reading file");
    }
    else
    {
        fseek(file , pos , SEEK_CUR);
        fgets(line, sizeof(line), file);
        printf("%s", line);
    }
    pos = ftell(file);

    return 0;
}

【讨论】:

  • 不应该在函数结束时关闭文件吗?而且我还怀疑如果你调用这个函数,它会多次打印最后一行(这只是一个预感:))
【解决方案2】:

避免重复打开文件是个好主意。不要每次调用函数时都打开文件,而是打开一次,然后每次调用时将文件指针传递给函数。

int * get_number(FILE *file)
{
    char line[256];

    fgets(line, sizeof(line), file);
    printf("%s", line);

    return 0;
}

int main()
{
    FILE *file = fopen("random_numbers.txt", "r");

    if (file == NULL) 
    {
        perror("Error opening file");
        return 1;
    }

    while (!feof(file))
    {
        get_number(file);
    }

    fclose(file);
}

【讨论】:

    【解决方案3】:
    1. 在调用函数中打开文件。

    2. FILE* 传递给get_number

    3. get_number返回int,而不是int*

    这是修改后的get_number

    int get_number(FILE* file)
    {
        // This is the core functionality.
        // You should add error handling code
    
        int number;
        int n = fscanf(file, "%d", &number);
        if ( n != 1 )
        {
           // Add error handling code.
        }
    
        return number;
    }
    

    【讨论】:

      【解决方案4】:

      这是正常的,因为每次调用 get_number(); 时都会打开文件; (这更糟,因为没有调用 fclose。 您想要的可能是在 get_number(); 处提供文件描述符;这样:

      void get_number(FILE*  file)
      {
      
          char line[256];
      
          if (file==NULL) 
              perror ("Bad descriptor given");
          else
          {
              if (fgets(line, sizeof(line), file) == NULL)
                   perror("Fgets failed"); 
              else
                   printf("%s", line);
          }
      }
      

      而您想要在您的职能之外执行以下操作:

      FILE * file = fopen("random_numbers.txt", "r");
      get_number(file); // 100
      get_number(file); // 200
      fclose(file);
      

      我让你的函数无效,因为这里的返回是没有意义的。您可以更改它并使用 atoi 和返回函数。

      【讨论】:

      • 应该检查fgets的返回值。
      猜你喜欢
      • 1970-01-01
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多