如何计算C文件中的行数?

时间:2019-06-05 20:45:12

标签: c

我有一个功能,该功能应该计算用户输入的文件中的行数。但是,无论何时输入文件,我的函数都会返回0行。

int findnum_lines(FILE* fp){

  int num_lines = 0;
  char line;
  int size;

  size = ftell(fp);
  line = getc(fp);
  if(size != 0){
    while(line != EOF){
      if(line == '\n'){
        num_lines = num_lines + 1;
      }
      line = getc(fp);
    }
  } else {
    num_lines = 0;
  }
  printf("%d", num_lines);
  return num_lines;
}

int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);

    num_lines = findnum_lines(fp);
    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}

我的示例文件是:

Hello Class
This is what I would call a normal file
It isn't very special
But it still is important

所以我的函数应该返回4行,而不是0。

已更新:

int findnum_lines(FILE* fp){

  int num_lines = 0;
  int line;

  line = getc(fp);

  while(line != EOF){
    if(line == '\n'){
      num_lines = num_lines + 1;
      }
    line = getc(fp);
    }
  printf("%d", num_lines);
  return num_lines;
}

int main(int argc, char* argv[]){
    char** lines = NULL;
    int num_lines = 0;
    FILE* fp = validate_input(argc, argv);

    num_lines = findnum_lines(fp);
    read_lines(fp, &lines, &num_lines);
    print_lines(lines, num_lines);
    free_lines(lines, num_lines);
    fclose(fp);

    return 0;
}

使用此更新的代码,不会打印num_lines。

2 个答案:

答案 0 :(得分:4)

ftell报告文件中的当前位置。对于刚刚打开的文件,位置是开始,ftell返回零。然后,由于size为零,因此findnum_lines中的循环处理零个字符,并报告未找到任何行。

通常,您不想获取文件大小然后循环播放。原因之一是文件在读取时可能会更改-其他进程可能会向其中写入更多数据或截断它。另一个原因是不必要的。只需使用EOF循环(或while循环)读取字符,直到获得do … while

另外,char line;应该是int line;,因为它用于保存getc的结果(可以是字符或EOF)和{{1 }}不足以容纳char。 (此外,EOF将字符的值作为getc转换为unsigned char的返回值,因此,在对int进行签名的实现中,char甚至不能正确地代表所有字符。)

答案 1 :(得分:2)

一个问题是对at main.Game.playSound(Game.java:102) at main.Game.playTreasureSound(Game.java:115) at main.Game.collisionCheck(Game.java:218) at main.Game.access$1(Game.java:200) at main.Game$1.handle(Game.java:240) at javafx.animation.AnimationTimer$AnimationTimerReceiver.lambda$handle$484(AnimationTimer.java:57) at java.security.AccessController.doPrivileged(Native Method) at javafx.animation.AnimationTimer$AnimationTimerReceiver.handle(AnimationTimer.java:56) at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:357) at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:506) at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490) at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) 的调用是在文件偏移仍为零的情况下完成的:

ftell()

如果在打开文件后立即调用int findnum_lines(FILE* fp){ int num_lines = 0; int line; // changed char to int int size; size = ftell(fp); line = getc(fp); if(size != 0){ while(line != EOF){ if(line == '\n'){ num_lines = num_lines + 1; } line = getc(fp); } } else { num_lines = 0; } printf("%d", num_lines); return num_lines; } ,则findnum_lines()返回的文件当前偏移量将位于文件的开头-或为零。

因此ftell()设置为零,并返回零。

请注意,由于要计算换行符-num_lines,因此不需要检查文件大小-长度为零的文件将包含零个换行符。