【问题标题】:How does getline work with cin?getline 如何与 cin 一起工作?
【发布时间】:2014-03-06 10:34:32
【问题描述】:

我觉得有很多类似的问题,所以如果这是重复的,我真的很抱歉。不过,我找不到这个特定问题的答案。

我对将 cin 传递给 getline 时的工作方式感到困惑,因为我的理解是它应该在每次调用时调用 cin。但是,在使用我正在阅读的书中的代码时,getline 被调用了几次,但只发送了一个输入。除了这些 getline 调用之外,不会从任何地方调用 cin 对象。

这里发生了什么?当到达 getline 时,程序是否只是停止在其轨道上并等待输入流传递一个包含所需分隔符的值?如果是这种情况,后续的 getline 调用是否不必等待,因为输入流已经包含包含它们各自分隔符的数据?我进行了一些测试,结果表明可能是这种情况。

代码如下:

    string firstName;
    getline(cin,firstName,',');

    string lastName;
    getline(cin,lastName,',');

    string job;
    getline(cin,job,'\n');

    cout<<firstName<<" "<<lastName<<" is a "<<job<<endl;;

再次抱歉,如果这是一个愚蠢的问题,但我环顾四周,真的找不到答案。提前感谢您提供的任何帮助!

澄清:

此代码为控制台输入“First,Last,Job\n”输出“First Last is a Job”

【问题讨论】:

  • 每一个都提取到包括分隔符在内的所有内容,因此它不可能在下一次调用时仍然存在。
  • @chris 除非有多个分隔符,否则它会停在第一个分隔符处。
  • @JS 你说“只发送一个输入”是什么意思?
  • @ooga 我在帖子末尾澄清了。
  • @ooga,没错,我想总是可以输入多余的内容:P 我想这也是问题所在。

标签: c++ input stream


【解决方案1】:

getline 根本不“呼叫”cincin 是一个对象。对象包含数据。 cin 中的数据是输入函数读取标准输入流所需的信息。例如,如果您想从文件中读取数据,您可以打开文件并将文件对象传递给 getline

当调用getline 时,程序会读取输入缓冲区中的任何内容。如果输入缓冲区已经包含分隔符,则getline 将立即返回。否则它会等待。

【讨论】:

  • 那么,如果输入分隔符在到达该行时不包含分隔符,则整个程序将冻结并仅在从流中接收到正确输入时才继续?
  • 酷,感谢您的帮助!我最初接受了本杰明林德利的回答,但我收回了它(对不起本杰明),因为我看到了你的名字。我认为你应该得到它,因为你在 cmets 之前对我做出了回应。再次感谢!
  • 他的更完整......但我会接受它!我会给他+1来弥补一点。 :-)
  • 啊,我不知道现在该怎么做才公平!哈哈,当我把复选标记切换给你时,我没有意识到他已经扩展了他的答案。
  • 他的回答比较完整。建议换回来。没有难过的感觉!
【解决方案2】:

使用cin 调用函数实际上并不是对用户输入的请求(至少不是直接请求)。它是对标准输入中的字符的请求。在正常的程序操作中(标准输入不是来自文件或其他源),标准输入存储在缓冲区中。如果标准输入缓冲区为空,并且cin 正在请求更多字符,那么您的系统将通过终端请求用户输入。 (即键盘)。终端请求的这个输入通常是面向行的。也就是说,它会等待您按下Enter 键,然后将所有要存储的数据发送到标准输入缓冲区中。如果cin 在输入缓冲区为空之前获得了它需要的所有字符,那么这些字符会一直保留到下一个请求。

因此,例如,当您拨打电话时:

getline(cin,firstName,',');

输入缓冲区是空的,假设用户输入了这个:

Benjamin, Lindley,软件开发人员Enter

首先,输入缓冲区中存储以下字符串:

"Benjamin, Lindley, Software Developer\n"

然后getline 导致从输入缓冲区读取"Benjamin,"(但丢弃逗号)。

" Lindley, Software Developer\n"

保留在缓冲区中以供将来使用 cin 进行的任何操作。

【讨论】:

  • 所以为了澄清一下,您正在确认我最初的猜测,即如果在当前输入流中看不到分隔符,程序会停止并等待直到收到正确的输入?
  • 我不知道我是怎么得到复选标记的!你是怎么把 Enter 键弄成这样的?
  • @ooga: &lt;kbd&gt;Enter&lt;/kbd&gt;
  • 不知道怎么办,心情不好!我最初给了你复选标记,但因为你的答案等同于 ooga 的答案而切换了它,而 ooga 在 cmets 中帮助我先行,但后来你更新了你的答案以更广泛!
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 2017-08-18
  • 2019-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
相关资源
最近更新 更多