12

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

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

这是我的代码:

#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;
}

任何的想法?

4

12 回答 12

20

如果您输出存储的内容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;
}

>输入您的号码后,您会看到它立即打印一个换行符。然后它继续输入其余部分。

这是因为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;
}

这按预期工作。

题外话,也许它只是为了手头的片段,但如果你没有using namespace std;. 它违背了命名空间的目的。不过,我怀疑这只是为了在这里发帖。

于 2010-01-11T05:05:36.793 回答
6

输入数字后,声明一个字符以进入回车符。char ws;int n;cin>>n;ws=cin.get(); 这将解决问题。

使用cin>>ws而不是ws=cin.get(),将使您的字符串的第一个字符成为变量ws,而不仅仅是清除'\n'

于 2017-02-05T13:03:59.570 回答
3

这很简单。U jst 需要在循环末尾放置一个 cin.get() 。

于 2020-03-07T10:37:01.637 回答
2

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

于 2010-01-11T04:35:04.427 回答
2

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

我会添加一些仪器:

int n;
cin >> n;
std::cerr << "n was read as: " << n << "\n"; // <- added instrumentation
for // ...
于 2010-01-11T04:35:54.337 回答
1
  • n 是否从输入正确初始化?
  • 您似乎没有对 getline 做任何事情。这是你想要的吗?
  • getline 返回一个 istream 引用。你把它丢在地上这一事实重要吗?
于 2010-01-11T04:35:24.437 回答
1

你在哪个编译器上试过这个?我在 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;
}
于 2010-01-11T04:58:38.103 回答
1

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

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

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

于 2010-01-11T07:57:54.713 回答
0

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

#include <iostream>
using namespace std;
int main()
{
    string str;
    getline(cin,str,'#');
    getline(cin,str,'#');
}

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

于 2018-01-04T10:13:25.020 回答
0

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

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

等等。

于 2021-06-08T05:53:55.237 回答
-1

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

于 2021-02-08T07:59:23.617 回答
-2

只需在 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;
}
于 2021-08-06T12:31:04.000 回答