首页 > 解决方案 > C++ cin.getline 忽略空行

问题描述

我有一个程序,它被赋予一个形状的文件并逐行读取它,以便能够将形状放入二维数组中。它的大小未知,所以我必须一边走一边数行数。一切正常,除了当输入后面有空行时我无法让它停止。

有问题的代码如下:

while(cin.eof() != true){
        getline(cin, input);

        shape = shape + input;
        rows++;
}

例如,这将计算 3 行:

===
===
===

这算4:

===
===
===
(empty line)

我需要我的程序忽略空行,不管有多少。我尝试了很多不同的东西,例如

if (!input.empty()){
        shape = shape + input;
        rows++;
}

或者

if (input != " " && input[0] != '\0' && input[0] != '\n'){
       shape = shape + input;
       rows++;
}

如果只有一个空行,这些工作,但如果我有多个空行,它只会不计算最后一个。

Shape 和 Input 都是字符串。

标签: c++

解决方案


您已经做出了一个很好的选择,一次读取一行getline(),但是您错误地控制了您的读取循环。请参阅为什么循环条件内的 !.eof() 总是错误的。

相反,始终根据读取函数本身产生的流状态来控制读取循环的继续。在您的情况下,您忽略之后的状态getline()并假设您有有效的输入——当您阅读EOF. 为什么?

当您读取文件中的最后一行时,您将已 read input,但eofbit尚未设置 ,因为您尚未到达文件末尾。您循环检查cin.eof() != true(还没有),然后调用getline (cin, input)BAM!没有读取任何内容,eofbit现在已设置,但shape = shape + input;即使您的读取getline()失败,您也会盲目分配。

您的第二个问题是如何跳过空行?简单的。如果input.size() == 0该行为空。要“跳过”空行,只需continue阅读下一个。要在到达第一个空行时“退出阅读”,请替换continuebreak.

一个包含上述更改的简短示例是:

#include <iostream>
#include <string>

int main (void) {

    std::string input{}, shape{};
    std::size_t rows = 0;

    while (getline(std::cin, input)) {      /* control loop with getline */
        if (input.size() == 0)              /* if .size() == 0, empty line */
            continue;                       /* get next */
        shape += input;                     /* add input to shape */
        rows++;                             /* increment rows */
    }

    std::cout << rows << " rows\n" << shape << '\n';
}

另请参阅:为什么“使用命名空间 std;” 被认为是不好的做法?并避免养成以后更难改掉的习惯。

示例使用/输出

$ cat << eof | ./bin/inputshape
> ===
> ===
> ===
> eof
3 rows
=========

末尾有一个空行

$ cat << eof | ./bin/inputshape
> ===
> ===
> ===
>
> eof
3 rows
=========

或者有多个空行:

$ cat << eof | ./bin/inputshape
> ===
> ===
> ===
>
>
> eof
3 rows
=========

注意:上面使用的eof输入只是标记输入结束的heredoc sigil,与流状态eofbit或没有独立意义.eof()。它也可以是banannas,但EOFeof通常/传统上使用。另外,如果你不使用 bash 或其他支持heredoc的 shell ,只需将文件重定向到程序,例如./bin/inputshape < yourfile

如果您还有其他问题,请仔细查看并告诉我。


编辑基于不使用continuebreak

如果您不能使用continueor break,那么只需将条件翻转并仅添加到shapeif input.size() != 0。例如:

    while (getline(std::cin, input)) {      /* control loop with getline */
        if (input.size() != 0) {            /* if .size() != 0, good line */
            shape += input;                 /* add input to shape */
            rows++;                         /* increment rows */
        }
    }

完全一样的东西,只是写的有点不同。让我知道这是否适合你。


推荐阅读