std::getline 在 for 循环中不起作用

Posted

技术标签:

【中文标题】std::getline 在 for 循环中不起作用【英文标题】:std::getline does not work inside a for-loop 【发布时间】:2011-01-03 15:19:50 【问题描述】:

我正在尝试在一个字符串变量中收集用户的输入,该变量在指定的时间内接受空格。

由于通常的 cin >> str 不接受空格,所以我会使用 std::getline from

这是我的代码:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()

    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    
        string local;
        getline(cin, local); // This simply does not work. Just skipped without a reason.
        //............................
    

    //............................
    return 0;

有什么想法吗?

【问题讨论】:

很少有事情会无缘无故地失败。 在 for 循环之前尝试以下操作: std::cout 是的。 n 被正确读取。我为 n 输入了 2,它打印出“n: 2” 我想我已经解决了你的问题。但是关于您的调试,您确实尝试了 2 以外的其他值,对吗?进入循环,它只是“跳过”第一个条目。 【参考方案1】:

如果您输出存储在local 中的内容(顺便说一句,这是一个糟糕的变量名:P),您就会明白为什么会失败:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()

    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    
        string local;
        getline(cin, local);
        std::cout << "> " << local << std::endl;
    

    //............................
    return 0;

您将看到它在输入您的号码后立即在&gt; 之后打印一个换行符。然后继续输入其余部分。

这是因为getline 为您提供了输入号码后剩下的空行。 (它会读取数字,但显然不会删除 \n,因此您会留下一个空白行。)您需要先删除任何剩余的空格:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()

    int n;
    cin >> n;
    cin >> ws; // stream out any whitespace
    for(int i = 0; i < n; i++)
    
        string local;
        getline(cin, local);
        std::cout << "> " << local << std::endl;
    

    //............................
    return 0;

这按预期工作。

题外话,也许它只是为了手头的 sn-p,但如果你没有using namespace std;,代码往往可读。它违背了命名空间的目的。不过,我怀疑这只是为了在这里发帖。

【讨论】:

我自己倾向于明确使用 std:: 命名空间前缀,但是在 cpp(不是 h)文件中使用 using 声明并没有错。 或许在这样一个简单的例子中。不过,在命名空间std 中有很多 的东西。函数级是我将使用using 指令的最全局性。【参考方案2】:

声明一个字符以在您输入数字后进入马车返回。char ws;int n;cin&gt;&gt;n;ws=cin.get(); 这样就可以解决问题了。

使用cin&gt;&gt;ws而不是ws=cin.get(),将使字符串的第一个字符位于变量ws中,而不是仅仅清除'\n'

【讨论】:

【参考方案3】:

这很简单。 你只需要在循环的末尾放一个 cin.get() 。

【讨论】:

【参考方案4】:

你按回车了吗?如果没有得到线将不会返回任何内容,因为它正在等待行尾......

【讨论】:

【参考方案5】:

我的猜测是你没有正确阅读n,所以它转换为零。由于 0 不小于 0,因此循环永远不会执行。

我会添加一些工具:

int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...

【讨论】:

没有。循环确实执行。我使用的是VC++ 2008,所以我可以通过逐行跟踪代码来调试。【参考方案6】: n 是否从输入正确初始化? 您似乎没有对 getline 进行任何操作。这是你想要的吗? getline 返回一个 istream 引用。你把它丢在地上这件事重要吗?

【讨论】:

是的。我尝试打印它,n 已正确初始化。 --- 我在getline之后把代码剪掉了。【参考方案7】:

你在哪个编译器上试过这个?我在 VC2008 上试过,效果很好。如果我在 g++ (GCC) 3.4.2 上编译了相同的代码。它不能正常工作。以下是在两个编译器中工作的版本。我的环境中没有最新的 g++ 编译器。

int n;
cin >> n;
string local;
getline(cin, local); // don't need this on VC2008. But need it on g++ 3.4.2. 
for (int i = 0; i < n; i++)

    getline(cin, local);
    cout << local;

【讨论】:

【参考方案8】:

重要的问题是“你对字符串做了什么,让你觉得输入被跳过了?”或者,更准确地说,“你为什么认为输入被跳过了?”

如果您正在单步调试调试器,您是否在编译时进行了优化(允许重新排序指令)?我不认为这是你的问题,但有可能。

我认为更有可能填充了字符串,但没有正确处理。例如,如果要将输入传递给旧的 C 函数(例如,atoi()),则需要提取 C 样式字符串(local.c_str())。

【讨论】:

【参考方案9】:

你可以直接在使用分隔符的字符串中使用getline函数,如下:

#include <iostream>
using namespace std;
int main()

    string str;
    getline(cin,str,'#');
    getline(cin,str,'#');

您可以根据需要多次输入 str,但这里适用的一个条件是您需要传递 '#'(第三个参数)作为分隔符,即字符串将接受输入,直到按下 '#' 为止,无论换行符如何。

【讨论】:

同样可以插入循环中。【参考方案10】:

getline(cin, local) 之前,只需添加if(i == 0) cin.ignore(); 。这将从字符串中删除最后一个字符 (\n),这会导致此问题,并且仅在第一个循环中需要它。否则,它将在每次迭代时从字符串中删除最后一个字符。例如,

i = 0 -> string
i = 1 -> strin
i = 2 -> stri

等等。

【讨论】:

【参考方案11】:

只需在循环前使用cin.sync()

【讨论】:

仅仅分发修复并没有帮助。请同时解释您的答案,以便对社区中的 OP 和其他人有益。背后的“原因”比“修复”更重要。【参考方案12】:

只需在 getline 之前添加 cin.ignore() 即可完成工作

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()

    int n;
    cin >> n;
    for(int i = 0; i < n; i++)
    
        string local;
        cin.ignore();
        getline(cin, local);
    

    return 0;

【讨论】:

这对 Pranav Rani 两个月前发布的答案有何改进?此外,他们提供了一个解释并且他们的答案有效。

以上是关于std::getline 在 for 循环中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

条件For循环在批处理文件中不起作用

简单的for循环在python中不起作用

为啥正常的 for 循环允许为结构字段分配值,而 for range 在 Golang 中不起作用? [复制]

for循环后的最后一个过程语句在pl sql中不起作用

for 循环中的代码在 ngOnInt() 中不起作用

Liquid - if contains 语句在 for 循环中不起作用