程序跳过cin.getline()

时间:2012-08-06 20:13:04

标签: c++ arrays string character-arrays

我制作了这个程序,它得到了用户的地址,名称和工作。然后它将所有内容放入一个字符串并输出该字符串。 (我知道有更好的方法可以做到这一点)

char str[600];
char adrs[200];
char name[10];
char wrk[200];
cout<<"Enter your name and press ENTER: ";
cin.getline(name,10);
cout<<"\nEnter your adress and press ENTER:";
cin.getline(adrs,200);
cout<<"\nEnter your workplace and press ENTER:";
cin.getline(wrk,200);
strcpy(str,"My name is ");
strcat(str,name);
strcat(str,"\nand i live at ");
strcat(str,adrs);
strcat(str, "\nI also work at ");
strcat(str, wrk); strcat(str, "\n\n");
cout<<str<<endl;

这里当我写一个超过10个字符的名字时程序确实采用了用户输入的前9个字符,但是之后它会跳过程序中的所有下一个cin.getline()并转到输出{ {1}}并结束该计划。

为什么会发生这种情况以及如何解决?

5 个答案:

答案 0 :(得分:8)

每次使用cin时,它都会存储在内存中输入的每个字符,直到遇到换行符。这块内存称为输入缓冲区。您对cin.getline()的第一次调用请求包含10个字符的字符串,包括终止NULL字符。但是,cin愉快地读取与用户类型一样多的字符,直到他按Enter键。如果用户输入的字符数超过9个,则cin会将剩余字符存储在输入缓冲区中,并在以后的输入操作中使用它们。例如,如果用户键入15个字符,则对cin.getline()的调用将存储c字符串数组中的前九个。再次调用cin.getline()将继续读取已输入的剩余输入。

要解决此问题,您应该使用cin.ignore()跳过此换行符。我强烈建议您熟悉C ++库的在线参考。我最喜欢的两个是http://www.cplusplus.comhttp://www.cppreference.com

编辑为了完成我的回答,我还需要补充一点,如果输入缓冲区中的字符数超过请求数,cin.getline()将设置失败位。在使用cin进行任何其他输入操作之前,必须调用cin.clear()来清除失败位。

答案 1 :(得分:3)

当读取太长的字符串时,为流设置ios_base::failbit,对流的所有后续操作都将失败。您需要使用ios::clear重置失败:

if (cin.fail())
    cin.clear();

清除错误后,您可能希望忽略istream::ignore的其余部分。

编辑:我花了一个有用的提示让我弄清楚如何正确使用ignore。这是整体解决方案。

cout<<"Enter your name and press ENTER: ";
cin.getline(name,10);
if (cin.fail())
{
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

我建议将所有代码放入函数中,以便每隔getline后调用一次。

答案 2 :(得分:2)

cin.getline(name,10);从输入中读取最多NINE字符,如果有换行符,则提前停止。如果这9个字符中没有换行符,则不会触及该行的其余部分,下次调用getline将继续读取该行的其余部分。

如果你想忽略输入行的其余部分,你可以使用:

cin.get(name, 10);
cin.ignore(INT_MAX, '\n');

答案 3 :(得分:1)

自由函数std::getlinestd::string上运行,比字符数组更容易处理。特别是,std::getline允许任意大的输入行。

试试这个:

std::string str;
std::string adrs;
std::string name;
std::string wrk;
cout<<"Enter your name and press ENTER: ";
std::getline(std::cin, name);
cout<<"\nEnter your adress and press ENTER:";
std::getline(std::cin, adrs);
...

答案 4 :(得分:0)

你的逻辑是合理的,问题在于,当你声明一个大小为10的字符数组时,你实际上并没有获得10个字符来输入字符,你只能获得9个字符。最后一个保留用于表示字符串的结尾。 [这里] [1]是一个参考,你想了解更多关于这个问题:

只声明一个字符多于您想要的数字。有许多关于如何刷新流的优秀提示,忽略了你可以使用的其他部分等。

祝你好运!