5

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

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()程序中的所有下一个字符,然后转到输出str并结束程序。

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

4

5 回答 5

8

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

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

编辑:为了使我的答案完整,我还需要添加cin.getline()如果输入缓冲区中的字符多于请求的字符,将设置失败位。在cin用于任何其他输入操作之前,您必须调用cin.clear()以清除失败位。

于 2012-08-06T20:24:51.927 回答
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.

于 2012-08-07T15:06:00.187 回答
2

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

如果您只想忽略输入行的其余部分,则可以改用:

cin.get(name, 10);
cin.ignore(INT_MAX, '\n');
于 2012-08-06T20:44:26.503 回答
1

free 函数std::getlinestd::strings 进行操作,这比字符数组更容易处理。特别是,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);
...
于 2012-08-06T21:10:09.903 回答
0

你的逻辑是合理的,问题是当你声明一个大小为 10 的 char 数组时,你实际上并没有得到 10 个位置来放置字符,你只得到了 9 个。最后一个保留以表示字符串的结尾。[这里][1] 是一个参考,您想了解更多关于这个问题的信息:

只需声明比您想要的数字多一个字符。关于如何刷新流、忽略行的其余部分等,您也可以使用许多出色的技巧。

祝你好运!

于 2012-08-06T21:04:31.640 回答