【问题标题】:Reading files with the same extension in a directory and count their lines在目录中读取具有相同扩展名的文件并计算它们的行数
【发布时间】:2019-10-13 07:17:16
【问题描述】:

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

    #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

【问题讨论】:

  • 这段代码对我来说很好用。您使用的是哪个操作系统?
  • 尝试 \r 而不是 \n
  • @RoyaGhasemzadeh 我使用的是 Windows 10 专业版
  • @RoyaGhasemzadeh 现在打印出 0

标签: c eof eol


【解决方案1】:

您展示的countLines() 函数正步入几个陷阱。

  1. fgetc() 有意返回 int 而不是 char。除了所有其他可能的字符值之外,它这样做是为了能够返回文件结束状态。一个简单的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' vs. Windows:\r\n vs. ... (https://en.wikipedia.org/wiki/Newline))。

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

【讨论】:

    猜你喜欢
    • 2019-05-21
    • 2017-08-31
    • 2010-12-28
    • 2017-09-29
    • 2017-05-09
    • 1970-01-01
    • 2019-03-26
    • 2018-03-29
    • 1970-01-01
    相关资源
    最近更新 更多