读取目录中具有相同扩展名的文件并计算它们的行数

Reading files with the same extension in a directory and count their lines

我的代码有这个问题。我一直在尝试打开具有相同扩展名的文件并读取目录中文件的行数。 所以,这就是我所做的:

    #include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
int countLines(char name[]);
int main()
{
    struct dirent *de;
    DIR *dr=opendir(".");
    char check[16]=".nkt";
    int i;
    char name[64];
    int count=0;

    if(dr==NULL)
    {
        printf("Didn't open!");
        return 0;
    }

    while((de=readdir(dr))!=NULL)
    {
        if((strstr(de->d_name, check))!=NULL)
        {
            strcpy(name, de->d_name);
            countLines(name);
        }
    }

    closedir(dr);

    return 0;
}

int countLines(char name[])
{
    FILE *fp;
    fp=fopen(name,"r");
    char ch;
    int lines=0;
    while(!feof(fp))
    {
        ch=fgetc(fp);
        if(ch=='\n')
        {
            lines++;
        }
    }

    fclose(fp);

    printf("%d\n", lines);
}

我得到的结果总是这样的:

2
2
2

即使每个文件有 54 行。 很乐意提供一些帮助。 PS。扩展名为 .nkt

您显示的 countLines() 函数正步入多个陷阱。

  1. fgetc() returns int 不是 char 故意的。它这样做是为了能够 return 文件结束状态,除了所有其他可能的字符值。一个简单的 char 无法做到这一点。

  2. 使用 feof() 识别文件结尾失败,因为 EOF 指示符仅在最后一次读取文件末尾完成后设置。因此,使用 feof() 引导的循环通常迭代一次到经常。

    对此的详细讨论是here

  3. 文本文件的最后一行不一定带有文件结束指示符,但您很可能仍想计算该行。需要应用特殊逻辑来涵盖这种情况。

解决上述所有问题的函数的可能实现可能如下所示:

#include <stdio.h>

/* Returns the number of lines inside the file named file_name 
   or -1 on error. */
long count_lines(const char * file_name)
{
  long lines = 0;
  FILE * fp = fopen(file_name, "r"); /* Open file to read in text mode. */
  if (NULL == fp)
  {
    lines = -1;
  }
  else
  {
    int previous = EOF;

    for (int current; (EOF != (current = fgetc(fp)));)
    {
      if ('\n' == current)
      {
        ++lines;
      }

      previous = current;
    }

    if (ferror(fp)) /* fgetc() returns EOF as well if an error occurred.
                       This call identifies that case. */
    {
      lines = -1;
    }
    else if (EOF != previous && '\n' != previous)
    {
      ++lines; /* Last line missed trailing new-line! */
    }

    fclose(fp);
  }

  return lines;
}

关于问题评论部分中关于不同行尾指示符的讨论:

文本文件的行尾指示器在不同平台上的实现方式不同(UNIX:'\n' 与 Windows:\r\n 与 ...(https://en.wikipedia.org/wiki/Newline)).

为了解决这个问题,C 库函数 fopen() 默认情况下以所谓的“文本模式”打开文件。如果以这种方式打开,C 实现会注意将每一行的结尾 return 编辑为单个 '\n' 字符,即所谓的“换行”字符。请注意(如上文 3. 所述)最后一行可能根本没有行尾指示符。