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

[求助]getline函数问题

kisscjy 发布于 2007-06-02 00:43, 2223 次点击

有段代码~~~

#include<iostream>
#include<string>
using namespace std;

void main()
{
int n;
cout<<"输入数字!"<<endl;
cin>>n;

string *fruit=new string [n];

for(int i=0; i<n; i++)
{
getline(cin,fruit[i]);
}
cout<<endl;

for(i=0; i<n; i++)
{
cout<<fruit[i]<<endl;
}

}

当我输入3次ASD的时候
程序只是输出两次ASD,
那还有一次去哪呢??

请高手指教~~

17 回复
#2
yushui2007-06-02 07:08

数组越界吧 字符串类型的最后一位都要存放NULL的阿

#3
herbert_19872007-06-02 08:39
#4
aipb20072007-06-02 09:43
以下是引用yushui在2007-6-2 7:08:07的发言:

数组越界吧 字符串类型的最后一位都要存放NULL的阿

#5
kisscjy2007-06-02 10:21

哦,谢谢了~~~

#6
wfpb2007-06-02 11:49

还是不懂,fruit[i]是一个string对象,为什么数组越界?
string str;
getline(cin,str);有问题吗?
然道不行?
谢谢说明白点。

#7
aipb20072007-06-02 12:08

说错了!

开始还以为是char数组来的。

跟踪了下,发现在读取fruit[0]的时候,会自动读取'\n',应该是跟输入流cin缓存区有关。

我也很想知道为什么,等待解答!

#8
yuyunliuhen2007-06-02 14:26

被截断了吧,如果是其他的编译器的话,就不会了是这样的结果了,比如说GCC++。这里也同样是这个问题,偶查了点资料,还是无头绪。https://bbs.bc-cn.net/dispbbs.asp?boardid=56&replyid=135595&id=137935&page=1&skin=0&star=2




#9
yuyunliuhen2007-06-02 17:03

对于C风格字符串,有如下输入方式:
char info[20];
cin>>info; //read a word;
cin.getline(info,20); // read a line ,discard \n
cin.get(info,20); //read aline ,leave \n in queue


对于string 对象,有两种输入方式:
string stuff;
cin>>stuff; //read a word
getline(cin,stubuf); // read a line discard\n


有两个版本的getline()都有一个参数,
用于指定哪个字符来确定输入的边界:
cin.getine(info,20,':') //read up to :,discard :
getline(stuff,':') ////read up to :,discard :

string 版本的getline()将自动调整string 对象的大小,使之刚好能存储输入的字符
char fname[10];
string lname;
cin>>fname; //could be a problem if input siae >9 characters

cin>>lname; //can read a very very long word
cin.getline(fname,10); //may truncate input
getline(cin,fname) ; //no truncate

string 的版本getline()的自动调节节大小的功能不需要指定输入的大小
string 版本的getline()从输入中读取字符,并将其存储在目标string 中,但有三种情况例外:
1:到达文件尾,这样,输入流的edfbit被设置,以为着方法file(),eof()都将返回true;
2:遇到分界字符,默认为‘\n’,这种情况下,将把分界字符从输入流中删除,而且不存储她;
3:读取的字符到达最大的允许值,它将设置输入流的failbit,这意味着fail()方法返回true; /////Attention !!!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我想下面的这段文字也可以解释LZ的问题。
(from MSDN)
string::getline :
Remarks

Note
The class/parameter names in the prototype do not match the version in the header file. Some have been modified to improve readability.

The getline function creates a string containing all of the characters from the input stream until one of the following situations occurs: - End of file. - The delimiter is encountered. - is.max_str elements have been extracted.

Example
Copy Code
// string_getline_sample.cpp
// compile with: /EHsc
// Illustrates how to use the getline function to read a
// line of text from the keyboard.
//
// Functions:
//
// getline Returns a string from the input stream.
//////////////////////////////////////////////////////////////////////

#pragma warning(disable:4786)
#include <string>
#include <iostream>

using namespace std ;

int main()
{
string s1;
cout << "Enter a sentence (use <space> as the delimiter): ";
getline(cin,s1, ' ');
cout << "You entered: " << s1 << endl;;
}

Input

test this

Sample Output

Enter a sentence (use <space> as the delimiter): test this
You entered: test


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The key as follows:
The getline function creates a string containing all of the characters from the input stream until one of the following situations occurs: - End of file. - The delimiter is encountered. - is.max_str elements have been extracted.


#10
kisscjy2007-06-02 18:37

确实是输入流cin 的缓存区有关~~
清空缓存区就可以了~~

但是为什么会自动读取 \n 呢?~~

#11
wfpb2007-06-03 11:33
因为cin>>num的原因,
流缓冲指针指向你输入的数字后的'\n',所以getline时就是直接从'\n'开始读取,因此:
input:
3
a
b
c

output:

a
b
可以看出,读的是:
"\n"
"a\n"
"b\n"
取的是:
""
"a"
"b"
#12
yuyunliuhen2007-06-03 13:26

to wfpb:
你分析的我也觉得有道理,但在G++下
#include<iostream>
#include<string>
using namespace std;

int main()
{
int n;
cout<<"输入数字!"<<endl;
cin>>n;

string *fruit=new string [n];

for(int i=0; i<n; i++)
{
getline(cin,fruit[i]);
}
cout<<endl;

for(int i=0; i<n; i++)
{
cout<<fruit[i]<<endl;
}

return 0;
}


input:
3
a
b


output:
a
b

也就是说,只能输入两次,这个是编译器的关系吧

#13
wfpb2007-06-03 15:13

两个编译器的头文件和库文件是不是都一样啊?比如说cin>>和getline的实现代码是不是一样啊?或者有关流操作的实现是不是都一样?

#14
aipb20072007-06-03 16:15
回复:(wfpb)两个编译器的头文件和库文件是不是都一...
我想这个应该要一样吧,不然怎么统一啊!

搞不懂!
#15
kai2007-06-03 17:00
try:

#include<iostream>
#include<string>
using namespace std;

int main()
{
  int n, i;
  cout<<\"Please enter a number: \";
  cin>>n;
  cin.clear();
  while(!isspace(cin.get()))
    continue;

    string * fruit=new string [n];
   
  for(i = 0; i<n; i++)
    getline(cin, fruit[i]);

     cout<<endl;

    for(i=0; i<n; i++)
    {
        cout<<fruit[i]<<endl;
    }
  return 0;
}

#16
aipb20072007-06-03 17:29
神,出现了。

kai, while(!isspace(cin.get()))
continue;
什么意思?

我们在讨论为什么第一次getline会自动读取cin缓冲区里的‘\n’。


#17
kai2007-06-03 17:54
楼主那段程序的问题就在那个cin>>n;
大家可以做一下实验,把那个n 赋个初值,比如3,然后把那个cin>>n; 去掉,问题就没有了。所以问题出现在这个cin上。

我的那段代码中的while, 就是用于补救cin 所造成的困境。

cin.clear() // reset stream state
while(!isspace(cin.get()))
continue; // get rid of bad input
#18
kai2007-06-03 17:55
这只是一些小技巧而已,只是知道和不知道的区别,没有什么。
1