c++ - 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 都是字符串。
解决方案
您已经做出了一个很好的选择,一次读取一行getline()
,但是您错误地控制了您的读取循环。请参阅为什么循环条件内的 !.eof() 总是错误的。
相反,始终根据读取函数本身产生的流状态来控制读取循环的继续。在您的情况下,您忽略之后的状态getline()
并假设您有有效的输入——当您阅读EOF
. 为什么?
当您读取文件中的最后一行时,您将已 read input
,但eofbit
尚未设置 ,因为您尚未到达文件末尾。您循环检查cin.eof() != true
(还没有),然后调用getline (cin, input)
BAM!没有读取任何内容,eofbit
现在已设置,但shape = shape + input;
即使您的读取getline()
失败,您也会盲目分配。
您的第二个问题是如何跳过空行?简单的。如果input.size() == 0
该行为空。要“跳过”空行,只需continue
阅读下一个。要在到达第一个空行时“退出阅读”,请替换continue
为break
.
一个包含上述更改的简短示例是:
#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
,但EOF
或eof
通常/传统上使用。另外,如果你不使用 bash 或其他支持heredoc的 shell ,只需将文件重定向到程序,例如./bin/inputshape < yourfile
)
如果您还有其他问题,请仔细查看并告诉我。
编辑基于不使用continue
或break
如果您不能使用continue
or break
,那么只需将条件翻转并仅添加到shape
if 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 */
}
}
完全一样的东西,只是写的有点不同。让我知道这是否适合你。
推荐阅读
- excel - 如何从 Excel 激活 Word 文档?
- laravel - Flutter - 使用 laravel api 进行条带支付
- node.js - 表达猫鼬填充问题
- ruby-on-rails - 自定义属性被忽略:不限于顶级 :root 元素 (:root { ... --font-size-tiny: ... }),在 atrule
- android - 我是否正确实施了 MVP 架构?
- html - 移动多个对象的 CSS 动画
- c++ - SetPos() 在 MainWindow 之外无法正确显示
- netlogo - 海龟在到达特定补丁时不会改变航向
- sql - 连接两个表并获取给定名称的最新记录
- c# - 在 XPather.com 上使用 XML 命名空间的奇怪 XPath 行为?