何时以及为什么我需要在c++中使用cin.ignore()
When and why do I need to use cin.ignore() in C++?
我用c++写了一个非常基本的程序,要求用户先输入一个数字,然后输入一个字符串。令我惊讶的是,当运行程序时,它从来没有停下来询问字符串。它只是跳过了它。在阅读了StackOverflow之后,我发现我需要添加一行:
cin.ignore(256, 'n');
放在获取字符串输入的行之前。添加了这些内容,就可以修复问题并使程序正常工作。我的问题是为什么c++需要cin.ignore()
行,以及我如何预测何时需要使用cin.ignore()
?
下面是我写的程序:
#include <iostream>
#include <string>
using namespace std;
int main()
{
double num;
string mystr;
cout << "Please enter a number: " << "n";
cin >> num;
cout << "Your number is: " << num << "n";
cin.ignore(256, 'n'); // Why do I need this line?
cout << "Please enter your name: n";
getline (cin, mystr);
cout << "So your name is " << mystr << "?n";
cout << "Have a nice day. n";
}
ignore
做的正是名字所暗示的。
它不会';throw away ';你不需要的东西。相反,它会忽略调用它时指定的字符数,直到指定为分隔符的字符。
它同时适用于输入和输出缓冲区。
本质上,对于std::cin
语句,您在执行getline
调用之前使用ignore
,因为当用户使用std::cin
输入某些内容时,他们按回车键,'n'
字符进入cin
缓冲区。然后,如果您使用getline
,它将获得换行字符而不是您想要的字符串。所以你做一个std::cin.ignore(1000,'n')
,这应该清除缓冲区到你想要的字符串。(1000放在那里是为了跳过指定分隔符之前的特定数量的字符,在本例中是'n'
换行符。)
您考虑这个的方式是错误的。每次使用cin
或getline
时,您都在逻辑步骤中进行思考。首先要一个号码,然后要一个名字。这是对cin
的错误理解。因此,您会遇到竞争条件,因为您假设每次请求输入时流都是清空的。
如果你写的程序纯粹是为了输入,你会发现问题:
int main()
{
double num;
string mystr;
cin >> num;
getline(cin, mystr);
cout << "num=" << num << ",mystr='" << mystr << "'" << endl;
}
在上面,你会想,"首先得到一个数字。"因此,您输入123
并按enter键,您的输出将是num=123,mystr=''
。为什么呢?这是因为在流中有123n
, 123
被解析为num
变量,而n
仍在流中。默认情况下,读取getline
函数的文档,它将查找istream
,直到遇到n
。在本例中,由于n
在流中,因此看起来它"跳过"了。
要使上述工作,您必须输入123Hello World
,这将正确输出num=123,mystr='Hello World'
。或者你在cin
和getline
之间放一个cin.ignore
,这样它就会分解成你期望的逻辑步骤。
这就是您需要ignore
命令的原因。因为你考虑的是逻辑步骤,而不是流形式,所以你遇到了竞争条件。
再举一个学校里常见的代码例子:
int main()
{
int age;
string firstName;
string lastName;
cout << "First name: ";
cin >> firstName;
cout << "Last name: ";
cin >> lastName;
cout << "Age: ";
cin >> age;
cout << "Hello " << firstName << " " << lastName << "! You are " << age << " years old!" << endl;
}
以上似乎是合乎逻辑的步骤。先问名字,再问姓氏,然后问年龄。因此,如果执行John
输入,然后执行Doe
输入,然后执行19
输入,则应用程序可以在每个逻辑步骤中工作。如果你用"流"来思考它;你可以简单地在"名字"后面输入John Doe 19
。问题,它也会工作,似乎跳过剩下的问题。要使上面的步骤在逻辑步骤中工作,您需要为问题中的每个逻辑中断对剩余的流进行ignore
。
只要记住把你的程序输入想象成从一个"流"中读取。而且没有逻辑步骤。每次调用cin
时,它都是从流中读取的。如果用户输入了错误的输入,这将创建一个相当有bug的应用程序。例如,如果您输入的字符应该是cin >> double
,那么应用程序将产生一个看起来很奇怪的输出。
简短回答
为什么?因为在输入流中仍然有空白(回车、制表符、空格、换行符)。
什么时候?当你使用一些函数时,它们自己不会忽略前导空格。默认情况下,Cin会忽略并删除前导空格,但getline本身不会忽略前导空格。
现在是详细的答案
在控制台中输入的所有内容都是从标准流stdin中读取的。当您输入某些内容时,假设在您的示例中为256并按enter键,流的内容将变为256n
。现在cin拾取256并将其从流中移除,n
仍然留在流中。现在,当您输入您的名称时,比如Raddicus
,流的新内容是nRaddicus
。
现在问题来了。当您尝试使用getline读取一行时,如果没有提供任何分隔符作为第三个参数,则getline默认情况下读取到换行符并从流中删除换行符。所以在调用newline时,getline从流中读取并丢弃n
,并导致在mystr中读取一个空字符串,看起来像getline被跳过(但不是),因为流中已经有一个换行符,getline不会提示输入,因为它已经读取了它应该读取的内容。
现在,我们来看看忽略这里的帮助?
根据忽略文档从cplusplus.com中提取-
istream&
从输入序列中提取字符并丢弃它们,直到或者已经提取了n个字符,或者一个比较等于delim .
如果文件结束符是,该函数也会停止提取字符达成。如果提前达到这个值(在提取n之前)字符或查找delim),该函数设置eofbit标志。
因此,cin.ignore(256, 'n');
忽略前256个字符或所有字符,直到遇到分隔符(这里是n),以先到者为准(这里n是第一个字符,所以它忽略直到遇到n)。
仅供参考,如果您不确切知道要跳过多少字符,并且您的唯一目的是清除流以准备使用getline或cin读取字符串,则应该使用cin.ignore(numeric_limits<streamsize>::max(),'n')
。
快速解释:它忽略等于流最大大小的字符,或者直到遇到'n',以先发生的情况为准。
当您想手动从输入流中丢弃特定数量的字符时。
一个非常常见的用例是使用它来安全地忽略换行符,因为cin有时会留下换行符,您必须经过这些换行符才能进入下一行输入。
长话短说,它给你处理流输入时的灵活性。
Ignore函数用于跳过(丢弃/丢弃)输入流中的字符。忽略文件与文件istream相关联。考虑下面的函数例:cin.ignore (120 '/n ');特定的函数跳过下一个120个输入字符或跳过字符,直到读取换行字符。
许多其他用户都指出了这一点。这是因为可能有空格或换行符。
考虑下面的代码,它从给定的字符串中删除所有重复的字符。
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin>>t;
cin.ignore(); //Notice that this cin.ignore() is really crucial for any extra whitespace or newline character
while(t--){
vector<int> v(256,0);
string s;
getline(cin,s);
string s2;
for(int i=0;i<s.size();i++){
if (v[s[i]]) continue;
else{
s2.push_back(s[i]);
v[s[i]]++;
}
}
cout<<s2<<endl;
}
return 0;
}
所以,你知道它会忽略那些不需要的输入并完成工作。
在c++中使用scanf(" %[^n]",str)比在cin>>语句后使用cin.ignore()更好。要做到这一点,首先你必须包含<</p>
- C++中的cin.ignore()函数不适用于整个流
- C++ cin.ignore() 跳过循环
- 更好的方法,而不是在C ++中使用cin.ignore
- C++ - 如何知道在哪里放置 cin.ignore
- C++:忽略第一个 cin.ignore 之后的输入
- cin.ignore() 正在产生不需要的行为
- 如何将光标移动到 cin.clear() 和 cin.ignore() 之后的文本输出末尾?
- C++ cin.ignore and getline in while loop
- CIN被跳过,Cin.ignore不起作用
- CIN.IGNORE删除第一个字符的第二次函数被调用
- cin.ignore(1)之间的分歧是什么?和cin.ignore(n)
- 使用 cin.ignore 和 cin.clear CPP 时的奇怪行为
- 为什么在"cin"后使用 "getline" 时需要 cin.ignore(),而多次使用 "cin" 时不需要?
- getline删除第一个字符;删除cin.ignore();无法解决
- C++怪异的cin.ignore行为
- Cin 不会暂停输入,尽管同时使用了 cin.clear() 和 cin.ignore()
- 当循环不中断时,使用 cin.ignore 和 cin.clear() 来验证输入
- CIN.IGNORE如何与CIN和Getline一起工作
- 尽管Cin.ignore(),CIN不等待输入
- cin.clear() 和 cin.ignore() 不起作用