【问题标题】:Does getline() not extract the delimiter?getline() 不提取分隔符吗?
【发布时间】:2018-11-09 04:49:40
【问题描述】:

所以我输入了一些整数,然后输入了一些句子。

这段代码运行良好:

#include<bits/stdc++.h>
using namespace std;
main(){
    int c,b,n,i;string s;
    cin>>n>>b>>c;
    for(i=0;i<n;i++){
        cin>>ws;
        getline(cin,s,'\n');
        cout<<s; 
     }
    }

例子:

3 3 3
This is weird
This is weirdDefinitely makes
Definitely makesNo sense
No sense

但是,当我尝试在 forloop 中省略 cin>>ws 时,它不能正常工作,例如这个代码段,

#include<bits/stdc++.h>
using namespace std;
main(){
    int c,b,n,i;string s;
    cin>>n>>b>>c;
    for(i=0;i<n;i++){
            getline(cin,s,'\n');
            cout<<s;
    }
}

例子:

3 3 3
This is weird
This is weirdDefinitely makes
Definitely makes

.. 并在那里终止,而不是采用所有三个输入。 这是为什么? cin>>ws 从输入中提取所有空格,但 getline() 不是也这样做吗?那么为什么当我在 forloop 中省略 cin>>ws 时它不能正常工作呢?

【问题讨论】:

  • 实际问题是什么:使用std::ws 的代码以何种方式无法按预期工作?
  • 您是从文件重定向输入还是实际在控制台输入?
  • @DietmarKühl 问题是如果我在 forloop 中省略了 cin>>ws ,它就不能正确输入,这是为什么呢?
  • @MarkRansom 在控制台输入
  • “无法正确输入”是什么意思?理想情况下,提供输入和预期输出,或者更好的是,使用std::istringstream 演示问题。

标签: c++ getline


【解决方案1】:

std::getline() 提取字符直到提取第一个分隔符(默认为'\n')。分隔符不存储在结果中,但会被提取。它确实提取一般的空格或多个分隔符。

顺便说一句:总是检查输入是否在尝试读取值之后工作。

在打印的示例中,问题是在格式化输入后,即使用&gt;&gt; 运算符后,没有提取空格。也就是说,对std::getline() 的第一次调用提取由初始换行符终止的空字符串。在格式化和未格式化的 I/O 之间切换时,通常需要提取尾随空格。也就是说,您需要类似的代码

if (cin>>n>>b>>c >> std::ws) {
    for(i=0;i<n;i++){
        if (getline(cin,s,'\n')) {
            cout << "i=" << i << ":'" << s << "'\n";
        }
    }
}

如果不添加成功检查,我无法推荐输入操作。更改了输出以使其更容易看到正在发生的事情:尝试带有/不带有此特定 std::endl 的代码以查看发生了什么。

【讨论】:

  • 清除它。谢谢:D
【解决方案2】:

当您使用cin &gt;&gt; 时,它不会删除输入后的任何空格。这意味着终止前 3 个输入的换行符仍在缓冲区中,等待第一个 getline 读取。由于换行符之前没有任何内容,因此第一个 getline 传递了一个空字符串。你的输出应该包含一个换行符,这样你就可以看到空行,那么它就有意义了。

最初,您发布的代码在 for 循环之前显示了一个 cin &gt;&gt; ws,这可以消除此问题。

【讨论】:

    【解决方案3】:

    getline() 的默认分隔符是 '\n',因此不需要在 getline 调用中包含它,但它不应该改变功能。

    例如见Same as getline(input, str, input.widen('\n')), that is, the default delimiter is the endline character.

    @DietmarKühl 解释说,从整数输入到 getline() 输入的格式更改会在整数后留下一些空格 (endl)。

    您可以更改 getline() 调用以消除分隔符为

    getline(cin,s);

    这将导致 getline() 使用 '\n' 作为默认分隔符。

    我已经修改了“n”变量来计数并删除了其他整数,以使代码更易于阅读:

    #include <iostream>
    
    int main()
    {
        int i;  // index
        int count;  // number of strings to accept
        std::string str;
    
        std::cout << "Input the number of strings you would like me to process: " << std::endl;
        std::cin >> count;
    
        if (std::cin >> count >> std::ws) {
            for (i = 0; i < count; i++) {
                if (getline(std::cin, str)) {
                    std::cout << "i=" << i << ":'" << str << "'\n";
                }
            }
        }
    }
    

    【讨论】:

    • 这实际上是不正确的:getline() 有两个原因停止:找到分隔符或找到流的末尾。如果它不是使用的分隔符,它不会在换行符处停止。
    • 改变了,同样的事情发生了。
    【解决方案4】:

    Cin 不会提取所有空格,它只会获取第一个单词,直到第一个空格。这就像有一个带有空格分隔符的 getline(不完全但接近)。

    Getline 采用整行并具有上面提到的默认 '\n' 分隔符。

    例如:

    string a = "Stack Overflow is awesome";
    

    可以给你 Stack 和 getline 会给你该行的一切

    【讨论】:

    • Re: "cin 只是提取单词" -- std::cin 没有提取任何东西。 &gt;&gt;getline 从输入流中提取字符;当您将 std::cin 传递给这些函数时,它们会从中提取字符。
    猜你喜欢
    • 1970-01-01
    • 2013-02-10
    • 2013-10-21
    • 2012-03-05
    • 2014-04-28
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 2017-03-02
    相关资源
    最近更新 更多