注册 登录
编程论坛 C++教室

一个getline和cin.geline这两个函数的区别

zhen16 发布于 2007-03-09 18:52, 4794 次点击
这两个函数同时是存储一个句子,用getline函数时,当输入一个字符串时,要敲两下回车,这个语句才结束,而用cin.getline则不用
当我运行这个程序时
#include <iostream>
#include <string>
using namespace std;
main ()
{
string name;
getline (cin, name);
cout <<name;
}
要想执行cout这个语句时,要敲两次回车才可以,当我输入one sentence[ENTER]时,它并不运行cout这个语句,而是光标还在编绎窗口上闪动,要再按一下[ENTER]才会运行cout这个语句,
而下面这个用cin.getline函数就不用,
#include <iostream>
#include <string>
using namespace std;
main ()
{
char name[100];
cin.getline (name , 100);
cout <<name;
}
而这个程序当我输入one sentence[ENTER]时就会运行cout这个语句,请高手解答一下
17 回复
#2
dlcdavid2007-03-09 23:43

应该是一样的吧, 都是一个函数

下面那个程序,用string不用char[]试试呢?

#3
yuyunliuhen2007-03-10 00:36

getline()
Syntax:
#include <string>
istream& getline( istream& is, string& s, char delimiter = '\n' );

The C++ string class defines the global function getline() to read strings from and I/O stream. The getline() function, which is not part of the string class, reads a line from is and stores it into s. If a character delimiter is specified, then getline() will use delimiter to decide when to stop reading data.

For example, the following code reads a line of text from STDIN and displays it to STDOUT:

string s;
getline( cin, s );
cout << "You entered " << s << endl;

getline()是一个流类库的一个成员函数,其书写形式是:

cin.geline(v,n);// getline()和cin.geline()应该是一样 ,只是参数不同,

其中参数v用来指定存放字符串的缓冲区地址,第二个参数n指定缓冲区长度。
使用getline(cin,i,?)函数可以输入带空格的整行字符 ,第三个参数默认为'\n'

#4
zhen162007-03-11 22:31

谢谢了,不过还是不太懂,因为我想问的是为什么getline函数要敲两次回车才会执行完该语句,而cin.getline只需一次就行了

#5
wfpb2007-03-12 21:58

lz没提出来,我还真没注意这个问题,后来查了下MSDN,想想会不会是如下原因,望大家一起讨论。。。

istream::getline:
Extracts characters from the stream until either the delimiter delim is found, the limit nCount–1 is reached, or end of file is reached. The characters are stored in the specified array followed by a null terminator. If the delimiter is found, it is extracted but not stored.

The second template function replaces the sequence controlled by str with a sequence of elements extracted from the stream is. In order of testing, extraction stops:
1、At end of file.
2、After the function extracts an element that compares equal to delim, in which case the element is neither put back nor appended to the controlled sequence.
3、After the function extracts is.max_size() elements, in which case the function calls setstate(ios_base::failbit).

也就是说,cin.getline执行时,当用户输入一个回车后,cin.getline从istream中吸取出\n(但是不store),然后函数结束.getline则是把第一个\n当作一行语句中的一个字符对待,因此第二个回车才是函数结束的标志(我总觉得和put back这句有关,但是我的解释还有一点问题,就是put back到底做了什么,getline中有这句,cin.getline没有这句,他们是在这有区别吗?)

#6
csight2007-03-12 22:27
1.istream& getline( istream& is, string& s, char delimiter = '\n' );
2.cin.getline(string &,LENGTH,char delimiter = '\n' );
是两个不同的函数;
一个是属于string;
一个是属于istream流;
#7
wfpb2007-03-13 13:49

呵呵,ls开玩笑,不过他们都是做和流有关的处理,只是处理流里面的缓冲时,稍微有一点不同。

#8
litcatyx2007-03-13 21:55
我这里敲一次回车就可以了,我用的是vs2005
#9
litcatyx2007-03-13 22:15
以下是摘自CSDN上的一段文字


FIX: getline Template Function Reads Extra Character
修正: getline 模板函数读取额外字符


RESOLUTION
解决方案

Modify the getline member function, which can be found in the following system header file "string", as follows:
在系统头文件 string 中,修改 getline 成员函数的内容为以下形式(用记事本查找以下代码段定位):

else if (_Tr::eq((_E)_C, _D))
{_Chg = true;

// _I.rdbuf()->snextc(); // 删除这一行,加上以下一行
_I.rdbuf()->sbumpc();
break; }




STATUS
状态

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.
微软已经证实这是列在本文开始处微软产品中发现的 Bug (这个中文怎么说来着?).

This problem was corrected in Microsoft Visual C++ .NET.
该问题已在 Microsoft Visual C++.NET 中修正.


MORE INFORMATION
更多信息

The following sample program demonstrates the bug:
以下程序演示该 Bug:

//test.cpp

#include <string>
#include <iostream>
int main () {
std::string s,s2;
std::getline(std::cin,s);
std::getline(std::cin,s2);
std::cout << s <<'\t'<< s2 << std::endl;
return 0;
}



//Actual Results:
//实际结果

Hello<Enter Key>
World<Enter Key>
<Enter Key>
Hello World



//Expected Results:
//预期结果

Hello<Enter Key>
World<Enter Key>
Hello World
#10
yuyunliuhen2007-03-13 22:17
同意楼上
#11
song42007-03-13 22:38
以下是引用wfpb在2007-3-12 21:58:36的发言:

lz没提出来,我还真没注意这个问题,后来查了下MSDN,想想会不会是如下原因,望大家一起讨论。。。

istream::getline:
Extracts characters from the stream until either the delimiter delim is found, the limit nCount–1 is reached, or end of file is reached. The characters are stored in the specified array followed by a null terminator. If the delimiter is found, it is extracted but not stored.

The second template function replaces the sequence controlled by str with a sequence of elements extracted from the stream is. In order of testing, extraction stops:
1、At end of file.
2、After the function extracts an element that compares equal to delim, in which case the element is neither put back nor appended to the controlled sequence.
3、After the function extracts is.max_size() elements, in which case the function calls setstate(ios_base::failbit).

也就是说,cin.getline执行时,当用户输入一个回车后,cin.getline从istream中吸取出\n(但是不store),然后函数结束.getline则是把第一个\n当作一行语句中的一个字符对待,因此第二个回车才是函数结束的标志(我总觉得和put back这句有关,但是我的解释还有一点问题,就是put back到底做了什么,getline中有这句,cin.getline没有这句,他们是在这有区别吗?)

这个正确

#12
wfpb2007-03-13 23:28

呵呵,song4,你来了,看来这次你支持错了。

的确如litcatyx所说,这是VC6的BUG, 我用标准编译器MinGW和Dev试过了,都是只有一个回车就输出了。

也就是说,这是因为VC6对标准C++的不完全支持所导致。

#13
song42007-03-14 11:23
不对啊
我文件操作总用这个啊
我在C++。。。。(程序设计???)那个经典的书里面见过啊
一个读回车,一个不读
#14
song42007-03-14 11:24

没细读他的文章
原来真是BUG,那只能怪书旧了。。。
#15
dlcdavid2007-03-14 20:22
getline(is, size, delim)//从is中读字符并存储到sink.
//直到文件结速或读到delim(在本例中为\n)
//读取delim然后丢弃delim.(从流中提取了delim,不放到sink中).
很可能是BUG,就像单步执行那样,输入\n,读入并丢弃按理说应该就退出了.
但是也许丢弃\n后并没有退出,而是暂停了,
再输入\n才激活函数然后才退出
注意:红字部分纯属虚构

getline原型:
template<class CharType, class Traits, class Allocator>
basic_istream<CharType, Traits>& getline(
basic_istream<CharType, Traits>& _lstr,
basic_istream<CharType, Traits, Allocator>& _Str,
CharType _Delim
);

[此贴子已经被作者于2007-3-14 21:09:45编辑过]

#16
yuyunliuhen2007-03-14 21:58
以下是引用dlcdavid在2007-3-14 20:22:32的发言:

很可能是BUG,就像单步执行那样,输入\n,读入并丢弃按理说应该就退出了.
但是也许丢弃\n后并没有退出,而是暂停了,
再输入\n才激活函数然后才退出
注意:红字部分纯属虚构



LS这个是什么意思呀?你的意思是说应该这样的
getline(is, size, delim)//从is中读字符并存储到sink.
//直到文件结速或读到delim(在本例中为\n)
//读取delim然后丢弃delim.(从流中提取了delim,不放到sink中).

#17
bill88882007-03-15 00:41

这还是个问题,我刚才试过了,确实跟编译器有关,我在dev c++里就只需要输入一个回车
但是又在vc++里试了一下,这里就需要敲击两下回车才显示

#18
zhen162007-03-15 13:01
真的很感谢名位可能真的是VC6的BUG吧,要其它编绎器中没有这问题
1