计算文件中的行,不包括C中的空行

时间:2015-06-11 22:07:01

标签: c count lines

我们有一个程序将文件作为输入,然后计算该文件中的行,但不计算空行。

Stack Overflow中已经有一篇关于这个问题的帖子,但答案并不能解决这个问题。

我们举一个简单的例子。

文件:

I am John\n
I am 22 years old\n
I live in England\n

如果最后一个' \ n'没有存在,那么计算就很容易了。实际上我们已经有了一个功能:

/* Reads a file and returns the number of lines in this file. */
uint32_t countLines(FILE *file) {
  uint32_t lines = 0;
  int32_t c;
  while (EOF != (c = fgetc(file))) {
    if (c == '\n') {
      ++lines;
    }
  }
  /* Reset the file pointer to the start of the file */
  rewind(file);
  return lines;
}

此功能在将上述文件作为输入时,计算4行。但我只想要3行。

我试图以多种方式解决这个问题。

首先,我尝试在每一行中执行fgets并将该行与字符串" \ 0"进行比较。如果一条线只是" \ 0"没有别的,那么我认为这样可以解决问题。

我也尝试了其他一些解决方案,但我找不到任何解决方案。

我基本上想要检查文件中的最后一个字符(不包括' \ 0')并检查它是否是' \ n'。如果是,则从先前计数的行数中减去1(使用原始函数)。我不知道如何做到这一点。还有其他更简单的方法吗?

我很感激任何类型的帮助。 感谢。

4 个答案:

答案 0 :(得分:4)

您实际上可以通过跟踪最后一个字符来非常有效地修改此问题。

这是有效的,因为空行具有前一个字符必须是\n的属性。

/* Reads a file and returns the number of lines in this file. */
uint32_t countLines(FILE *file) {
  uint32_t lines = 0;
  int32_t c;
  int32_t last = '\n';
  while (EOF != (c = fgetc(file))) {
    if (c == '\n' && last != '\n') {
      ++lines;
    }
    last = c;
  }
  /* Reset the file pointer to the start of the file */
  rewind(file);
  return lines;
}

答案 1 :(得分:2)

这是一个稍好的算法。

#include <stdio.h>

// Reads a file and returns the number of lines in it, ignoring empty lines
unsigned int countLines(FILE *file)
{
    unsigned int  lines = 0;
    int           c = '\0';
    int           pc = '\n';

    while (c = fgetc(file), c != EOF)
    {
        if (c == '\n'  &&  pc != '\n')
            lines++;
        pc = c;
    }
    if (pc != '\n')
        lines++;

    return lines;
}

只计算任何换行序列中的第一个换行符,因为除第一个换行符外的所有换行符都表示空行。

请注意,如果文件没有以'\n'换行符结尾,则遇到的任何字符(超出最后一个换行符)都被视为部分最后一行。这意味着读取没有换行符的文件会返回1。

读取空文件将返回0.

读取以单个换行符结尾的文件将返回1.

(我删除了rewind(),因为没有必要。)

答案 2 :(得分:0)

首先,检测仅由空格组成的行。所以让我们创建一个函数来做到这一点。

bool stringIsOnlyWhitespace(const char * line) {
    int i;
    for (i=0; line[i] != '\0'; ++i)
        if (!isspace(line[i]))
            return false;
    return true;
}

现在我们有了一个测试函数,让我们围绕它构建一个循环。

while (fgets(line, sizeof line, fp)) {
    if (! (stringIsOnlyWhitespace(line)))
        notemptyline++;
}

printf("\n The number of nonempty lines is: %d\n", notemptyline);

来源是比尔林奇,我有点改变。

答案 3 :(得分:0)

我认为使用fgets()的方法完全没问题。尝试这样的事情:

char line[200];

while(fgets(line, 200, file) != NULL) {
    if(strlen(line) <= 1) {
        lines++;
    }
}

如果您不知道文件中行的长度,可能需要检查line是否实际包含整行。

修改

当然这取决于你如何定义空行。如果您将只有空格的行定义为空,则上述代码将不起作用,因为strlen()包含空格。