istringstream忽略第一个字母
istringstream ignores first letter
我正在尝试使用std::istringstream
访问字符串中的不同单词,我也在使用多个测试用例。
int t;
cin>>t;
while(t--)
{
string arr;
cin.ignore();
getline(cin,arr);
istringstream iss(arr);
string word;
while(iss>>word)
{
cout<<word;
}
}
对于第一个测试用例,一切都是完美的(即输出正确的单词)。但对于随后的每个测试用例,第一个单词的第一个字母都会被忽略。
示例:
输入:
4嘿,嘿
嗨嗨
我的名字是xyz
女孩吃香蕉
我得到了:
输出:
嘿,嘿
i嗨嗨
y名称是xyz
irl吃香蕉
有人能告诉我该怎么做吗?为什么会出现这种错误?
您的问题是格式化的输入,即像in >> value
这样的输入,在尝试读取之前通常会跳过前导空格。另一方面,未格式化的输入不会跳过前导空格。使用循环中的std::cin.ignore();
,您可以假设std::getline(std::cin, arr)
会像t
的输入一样在输入中保留换行符。事实并非如此。std::getline()
提取并存储所有字符,直到它停止的第一个换行符,仍然提取换行符。因此,您应该从循环中删除cin.ignore();
。
关键问题是如何在格式化输入和非格式化输入之间切换。由于输入数值时的换行符前面可能有任意空格,您可能也想忽略这些空格,因此基本上有以下几种方法:
std::cin >> std::ws;
跳过所有前导空格。这可能包括多个换行符和行开头的空格。跳过这些可能并不一定是可取的std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
忽略第一个换行符之前(包括该换行符)的所有字符。这将允许空行跟在后面,也允许以前导空格开头的行
这一行是罪魁祸首:cin.ignore();
。
当在没有任何参数的情况下调用std::basic_istream::ignore
时,它只忽略1个字符。
在您的情况下,std::cin.ignore()
将忽略第一个字母,但对于第一个测试用例则不会,因为此时std::cin
为空,因此没有什么可忽略的。但是,std::cin
中有其他单词,因此它忽略了第一个单词中的1个字符。
根据std::basic_istream::ignore
:的文档
从输入流中提取并丢弃字符,直到和包括熟食ignore表现为UnformattedInputFunction
值得一提的是,如果流中没有可忽略的东西,std::basic_istream::ignore
将阻塞并等待用户输入。
考虑到这一点,让我们分解一下你的代码的作用:
- 第一次在循环中调用此函数时忽略仍在缓冲区中的换行符先前的CCD_ 17操作。然后
getline
语句将等待并读取来自用户的一行 - 下一次,由于缓冲区中没有任何内容忽略(因为
std::getline
没有在缓冲区),它将进入块并等待输入被忽略。所以下一次程序阻塞并等待输入时,是因为ignore()
函数,而不是像您希望的那样使用getline
函数希望,并且在你提供输入的那一刻(即你的第二次测试case),则将忽略输入中的一个字符 - 下一个
getline
函数将不会阻塞,因为存在某些内容在前一个ignore
函数之后留下的缓冲区中忽略输入的第一个字符,因此getline
将读取刚好短一个字符的剩余字符串 - 该过程从步骤2开始继续,直到循环终止
int t;
cin>>t;//this leaves new line character in the buffer
while(t--)
{
string arr;
cin.ignore();//this will ignore one character from the buffer,so the first time
//it will ignore the new line character from the previous cin input
//but next time it will block and wait for input to ignore
getline(cin,arr);//this will not block if there is something in the buffer
//to read
...
}
解决方案是将ignore
语句移出循环,移到cin>>t
语句旁边。在这种情况下最好编写ignore(INT_MAX,'n');
。您可能还想阅读这个答案,了解何时以及如何使用ignore
。
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- 如何仅读取文本文件中的第一个值
- 在C++中,如何在第一个"system()"结束后执行第二个"system()"?
- 查找不在标准中的第一个值::设置<int>最小-最大值
- C++:忽略第一个 cin.ignore 之后的输入
- 在C++中打印多个矢量的第一个值
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- C++第一个cout将不会打印
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- OpenGL:第二个VBO破坏了第一个VBO
- 为什么第一个Dynamic_cast没有投射到基类?
- OpenGL 2D游戏只绘制第二个精灵纹理而不是第一个
- C++ 为什么程序只读取第一个值
- 在我的第一个C++程序中需要一些帮助(简单)
- 为什么我的代码在第一个 if 语句处中断?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 无法使我的第一个Windows OpenGL窗口抬起并运行
- 将参数初始化为构造函数,而不是第一个
- 无法在硬件模式下创建 SGX 安全区 - "invalid launch token"即使文档将无效的启动令牌指定为第一个