【问题标题】:Count Blank Lines from a file in C从C中的文件中计算空白行
【发布时间】:2020-08-14 14:12:27
【问题描述】:

有没有办法用 C 语言计算文件中空行的总数。我一直在尝试,下面是我的代码,但它不起作用。

void countLines(char *f1)
{
  FILE *fp;
  fp=fopen(f1,"r");
  int d=fgetc(fp),count=0,countbl=0;
  while(d != EOF)
  {
    if(d=='\n')
    {
      d=fgetc(fp);
      if(d=='\n')
        countbl++;
      count++;
      fseek(fp,-1,SEEK_CUR);
    }

    d=fgetc(fp);
  }
  printf("%d %d",count+1,countbl);
}

当fgetc遇到\n时,我正在使用fgetc逐个字符读取文件我检查下一个字符是否再次\n,这意味着它是空行但它不起作用。

示例输入

fileCount.txt(name of text file)

文件内容

This is line one


Hello, welcome to programming

Code quotient - Get better at coding

b

样本输出

8 4

这里 8 是总行数,4 是空行总数。

这是新代码,但仍然无法正常工作

void countLines(char *f1)
{
  FILE *fp;
  fp=fopen(f1,"r");
  int d=fgetc(fp),count=0,countbl=0,temp=0;
  while(d != EOF)
  {
    //printf("%c %c",temp ,d);
    if(d=='\n' && temp=='\n' )
      countbl++;
    if(d=='\n')
    count++;
    temp=d;

    d=fgetc(fp);
  }
  printf("%d %d",count+1,countbl);
}

【问题讨论】:

  • fseek 有什么用?
  • fseekungetc 字符的一种繁琐方式。如果您保留先前读取的 char 的值(并将其初始化为 '\n',以便开头的换行符算作空行),则两者都是不必要的。向后看,而不是向前看。毕竟'\n'在一行的末尾,你对你已经看到的东西感兴趣。
  • @John3136 在第一个 if 条件下,d=fgetc(fp) 会将指针移动到下一个字符,以便将指针向后移动我使用过的fseek
  • fgets 不会遇到空行,它会遇到单个字符。作为程序员,您必须确定是否有空行。顺便说一句,您对两个连续换行符的定义非常狭窄。空行中可以有空格和制表符。
  • 请不要说“不工作”,而要努力描述什么不工作。你会得到哪些错误?您的实际输出与预期输出有何不同?

标签: c file file-handling fseek


【解决方案1】:

首先,让我们定义一个结构来保存行统计信息,以便我们可以从函数中返回 t:

struct linestat {
    size_t total;
    size_t blank;
};

接下来,让我们定义什么是空行。您对两个连续换行符的定义还可以,但是很窄,所以假设一个空白行仅由空格字符组成,并且由换行符终止。您可以使用<ctype.h> 中的函数isspace(c) 确定字符c 是否为空格。

你可以用不同的方式来解决这个问题。这是一种方法:

扫描一行,直到看到换行符,并跟踪您是否在途中遇到非空格。在您的统计数据中重新识别该行。重复。当然,你还必须检查你是否遇到EOF的:

struct linestat count_lines(const char *filename)
{
    struct linestat ls = {0, 0};
    FILE *fp = fopen(filename, "r");

    if (fp == 0) return ls;

    while (1) {
        int blank = 1;
        int c = fgetc(fp);

        while (c != EOF && c != '\n') {
            if (isspace(c) == 0) blank = 0;

            c = fgetc(fp);
        }

        if (c == EOF) break;

        ls.total++;
        if (blank) ls.blank++;
    }

    fclose(fp);

    return ls;
}

注意事项:

  • 该算法会跟踪它在途中看到的内容,这样您就不必在文件中向后跳转。 (有时,这样做并让单个字符未读可能很有用。在这种情况下,ungetcfseeking 更好。)
  • 我选择在这里使用while (1)break,因为我认为它更符合程序的工作方式。请注意,如果文件的最后一行没有以换行符正确终止,则不会考虑文件的最后一行。
  • 您应该发现无法打开给定文件进行读取的情况。在您 fopened 文件后,您必须确保稍后再 fclose

【讨论】:

    【解决方案2】:

    所以我使用了这个新代码,而不是计算空白行,我所做的是计算总行数和填充行总数,然后从总行数中减去填充行,它工作得很好,我不知道为什么@MOehm 建议的早期代码不起作用可能是由于编译器问题或我不知道。

    这里是代码

    void countLines(char *f1)
    {
      FILE *fp;
      fp=fopen(f1,"r");
      int count=0,countbl=0;
      char str[200],*c1;
      c1=fgets(str,200,fp);
      while(c1 != NULL)
      {
        if(c1[0]>=32 && c1[0]<=127)
        countbl++;
        c1=fgets(str,200,fp);
        count++;
      }
      printf(" %d %d",count,count-countbl);
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      相关资源
      最近更新 更多