c 文件 reader 处的无限循环

Infinite loop at file reader in c

我试图编写一个代码来计算另一个进程的平均执行时间(写下使用了多少内核以及完成所需的时间)。问题是它卡在了 linecounter() 函数中。

这是我将要阅读的示例 log.txt:

1 11.3484
1 10.8089
1 10.7293

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct result{
  double *runtime;
  int *size;
}R1;

int linecounter(FILE *fileptr)
{
  int count_lines=0;
  char chr=getc(fileptr);
  while (chr != EOF)
  {
    printf("Inside the linecounter function()\n");
    //Count whenever new line is encountered
    if (chr == '\n') //works because I dont have any N in my txt, take care
    {
      count_lines++;
    }
    //take next character from file.
    chr = getc(fileptr);
  }
  return count_lines;
}

int main()
{
  FILE *f;
  f=fopen("log.txt","r");
  if(f == NULL)
  {
    printf("Error! opening the file");   
    exit(1);             
  }
  printf("Counting lines\n");
  int n=linecounter(f);

  R1.runtime=malloc(n*sizeof(double));
  R1.size=malloc(n*sizeof(int));

  int j=1,k=0;
  printf("Reading file\n"); 
  j=fscanf(f,"%d %6.4f",&R1.size[k],&R1.runtime[k]); //First number of cores, then runtime
  k++;
  while(j!=EOF)
  {
    j=fscanf(f,"%d %6.4f",&R1.size[k],&R1.runtime[k]); //First number of cores, then runtime
    k++;
  }

  int AvgRuntime=0,i=0;

  if(R1.size[i]==1)
  {
    while(R1.size[i]==1) //for 1 core
    {
      AvgRuntime+=R1.runtime[i];
      i++;
    }
  }
  
  AvgRuntime=AvgRuntime/i;
  printf("Avg Runtime: %6.4f",AvgRuntime);
  int prev_i=i;
  AvgRuntime=0;
  if(R1.size[i]==2)
  {
    while(R1.size[i]==2) //for 2 core
    {
      AvgRuntime+=R1.runtime[i];
      i++;
    }
  }
  
  AvgRuntime=AvgRuntime/(i-prev_i);
  printf("Avg Runtime: %6.4f",AvgRuntime);
  prev_i=i;
  AvgRuntime=0;
  if(R1.size[i]==4)
  {
    while(R1.size[i]==4) //for 4 core
    {
      AvgRuntime+=R1.runtime[i];
      i++;
    }
  }
  
  AvgRuntime=AvgRuntime/(i-prev_i);
  printf("Avg Runtime: %6.4f",AvgRuntime);
  fclose(f);
  return 0;
}

这很简单,我有 3 个选项,使用 1、2 或 4 个内核,所以我计算每种情况的平均值并为下一种情况覆盖它。当试图获取文件中写入了多少行时,问题就来了。

通过在 linecounter 函数中添加 printf(),我注意到它永远不会到达文件末尾。有什么解决办法吗?

您的代码中有多个错误。

getc returns 一个 int,而不是 char。如果您的 char 默认情况下是无符号的,则它无法保存值 EOF 并且您的比较 chr != EOF 永远不会为真。

在您计算文件中的行数后,文件指针位于文件末尾。您无法从中读取任何进一步的价值。您必须倒带才能扫描内容。

您的格式说明符 %6.4fscanf 无效。您不能指定精度。您只能在打印值时执行此操作。

您的格式说明符 %f 需要 float* 作为参数,但您提供了 double*。对于 double 使用 %lf。您可以使用 %f 打印 floats,但必须使用 %lf 来打印 scanf

您使用 %6.4f 打印计算出的平均值,但 AvgRuntime 的类型为 int。 这也意味着平均值的计算是使用整数除法完成的。由于结果被截断,因此不会有任何小数。 将 AvgRuntime 改为 `double。

您的编译器应该会告诉您很多这样的问题。 如果您没有收到警告,您应该显着提高警告级别。 如果您确实收到了这些警告,是什么让您忽略了所有警告?

你也有逻辑错误。 只有对日志文件中的条目进行排序,您的平均才有效。您必须先读取核心 1 的所有行,然后读取核心 2 的所有行,然后再读取核心 4 的所有行。如果文件未排序,您的计算将失败。

此外,如果您没有核心条目,您将除以零,因为您不检查 iprev_i 的值。

最后,printfstdout 通常是行缓冲的。除非达到 \n,否则不会打印输出。当您打印平均值时,您应该在 printf 行的末尾添加一个 \n

固定版本(计算平均值的问题除外)可能如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct result{
  double *runtime;
  int *size;
}R1;

int linecounter(FILE *fileptr)
{
  int count_lines=0;
  int chr=getc(fileptr);
  while (chr != EOF)
  {
//    printf("Inside the linecounter function()\n");
    //Count whenever new line is encountered
    if (chr == '\n') //works because I dont have any N in my txt, take care
    {
      count_lines++;
    }
    //take next character from file.
    chr = getc(fileptr);
  }
  rewind (fileptr);
  return count_lines;
}

int main()
{
  FILE *f;
  f=fopen("log.txt","r");
  if(f == NULL)
  {
    printf("Error! opening the file");
    exit(1);
  }
  printf("Counting lines\n");
  int n=linecounter(f);

  R1.runtime=malloc(n*sizeof(double));
  R1.size=malloc(n*sizeof(int));

  int j=1,k=0;
  printf("Reading file\n");
  j=fscanf(f,"%d %lf",&R1.size[k],&R1.runtime[k]); //First number of cores, then runtime
  k++;
  while(j==2)
  {
    j=fscanf(f,"%d %lf",&R1.size[k],&R1.runtime[k]); //First number of cores, then runtime
    k++;
  }

  int i=0;
  double AvgRuntime=0.0;
  if(R1.size[i]==1)
  {
    while(R1.size[i]==1) //for 1 core
    {
      AvgRuntime+=R1.runtime[i];
      i++;
    }
  }
  AvgRuntime=AvgRuntime/i;
  printf("Avg Runtime: %6.4f\n",AvgRuntime);

  int prev_i=i;
  AvgRuntime=0.0;
  if(R1.size[i]==2)
  {
    while(R1.size[i]==2) //for 2 core
    {
      AvgRuntime+=R1.runtime[i];
      i++;
    }
  }
  AvgRuntime=AvgRuntime/(i-prev_i);
  printf("Avg Runtime: %6.4f\n",AvgRuntime);

  prev_i=i;
  AvgRuntime=0;
  if(R1.size[i]==4)
  {
    while(R1.size[i]==4) //for 4 core
    {
      AvgRuntime+=R1.runtime[i];
      i++;
    }
  }
  AvgRuntime=AvgRuntime/(i-prev_i);
  printf("Avg Runtime: %6.4f\n",AvgRuntime);

  fclose(f);
  return 0;
}

与您的文件一起输出:

Counting lines
Reading file
Avg Runtime: 10.9622
Avg Runtime:   -nan
Avg Runtime:   -nan