C++ --- getline 和 cin ignore () . 删除输出字符串中的第一个字符
Posted
技术标签:
【中文标题】C++ --- getline 和 cin ignore () . 删除输出字符串中的第一个字符【英文标题】:C++ --- getline, and cin ignore () .deleting first characters in strings on output 【发布时间】:2019-03-20 21:20:41 【问题描述】:#include <iostream>
#include <string>
using namespace std;
struct UserInfo
string userPhoneNumber;
string userName ;
string userAddress ;
;
int main ()
cout << "How many Entries do you want to enter?";
int userAmountSelection;
cin >> userAmountSelection;
UserInfo userOne [userAmountSelection];
for (int i = 0; i < userAmountSelection; i++)
cout << "Please enter your first and last name: ";
cin.ignore(); // possible problem in code
getline (cin, userOne[i].userName, '\n');
cout << "Please Enter your address, " << userOne[i].userName << ":";
cin.ignore(); // possible problem in code
getline (cin, userOne[i].userAddress, '\n');
cout << "Please enter your phone#: ";
cin.ignore (); // possible problem in code
getline (cin, userOne[i].userPhoneNumber);
for (int i = 0; i < userAmountSelection; i++)
cout << userOne[i].userName << " " <<
userOne[i].userAddress << " " <<
userOne[i].userPhoneNumber << endl;
return 0;
正如您所见,它是用于学习结构和实验的简单代码。我遇到的问题似乎来自 cin.ignore () 代码。它在输出时忽略输入字符串的第一个字符。代码确实可以编译,但是输入和输出有偏差。
比如我输入一个Terry的名字,就会输出erry。
我尝试删除cin.ignore ()
,但是当我这样做时,输出会跳过用户需要输入数据的部分并将区域留空。
我搜索了论坛并找到了一些建议,例如向cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
添加参数。例如,但这并不能解决问题,只会添加到我遇到的错误列表中。
【问题讨论】:
将ignore
s 放置在将不需要的内容留在流中的操作之后。如果您在操作之前ignore
,您经常会发现自己丢失了您想要的数据,因为ignore
没有任何数据。
不要将提取器与getline
混合使用。他们打架。而不是cin >> userAmountSelection;
将输入读入带有getline
的字符串,并将字符串中的文本转换为int
。
@pete becker --- 我明白你在说什么,我只是尝试实现它,如果我做得正确,它会给我使用 userAmountSelection 变量的错误。我不再能够在 UserInfo userOne [userAmountSelection] 中使用它;声明。
使用userAmountSelection
表示数组的大小是不合法的。一些编译器将其作为扩展提供。
【参考方案1】:
问题
问题在于ignore
s 的位置,以防止Why does std::getline() skip input after a formatted extraction? 中概述的错误ignore
s 已放置在getline
s 之前,虽然这解决了getline
跳过问题,但它导致提问者遇到的问题。并不总是需要忽略某些东西。
例如
cin >> userAmountSelection;
如果用户输入金额然后按回车键,则会在流中留下一行结尾。
cout << "Please enter your first and last name: ";
cin.ignore(); // possible problem in code
getline (cin, userOne[i].userName, '\n');
在for
循环内如果不是ignore
,将跳过此行结束。但是getline
不会在流中留下换行符,因此循环的第二次和后续迭代没有换行符可以忽略。部分所需数据改为ignored
。
之后
cin >> userAmountSelection;
而不是以前
getline (cin, userOne[i].userName, '\n');
将是放置ignore
的好地方,因此只有在将换行符留在流中后才会从流中删除它,但是...
解决方案
处理此问题的最佳方法是始终使用 getline
读取整行,然后将这些行 (see option 2 of this answer) 解析为您想要的部分。
std::string line;
std::getline(std::cin, line);
std::istringstream(line) >> userAmountSelection;
这总是有效的(注意:需要#include <sstream>
),现在您只有一种阅读方式,而不是混搭游戏,您可能会忘记需要ignore
。
请立即停止阅读。
ignore
方法需要一些额外的聪明才智。除了人类记忆的易错性之外,它并不像看起来那么简单。您应该将ignore
s 放置在将不需要的内容留在流中的操作之后。如果您在操作之前ignore
,您经常会发现自己丢失了您想要的数据,因为ignore
没有任何数据。
std::cin >> userAmountSelection; // read a number
std::cin.ignore(); // discard the next character
很多时候都有效,但是如果用户输入数量,然后输入一个空格,然后按回车键或输入他们需要输入的所有输入,因为他们很新,下一个提示是什么?你得有点狡猾。
std::cin >> userAmountSelection;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
这个ignore
会消灭所有东西,直到它到达行尾或流中的空间用完。 (注:需要#include <limits>
)
【讨论】:
#include 和 #includestringstream
的标头,基本上是cin
和cout
读取或写入string
而不是控制台。
好点。我从用户的代码开始,将其排除在外。为了完整起见,不妨将其重新添加。【参考方案2】:
我遇到的问题似乎来自 cin.ignore () 代码。它在输出时忽略输入字符串的第一个字符。
看着istream::ignore
declaration
istream& ignore (streamsize n = 1, int delim = EOF);
默认会丢弃第一个字符。
我已经尝试删除 cin.ignore(),但是当我这样做时, 输出跳过用户需要输入数据的部分和 将区域留空。
这是因为std::cin
的执行留下了剩余的换行符,然后被getline
消耗。您只需要在std::cin
和getline
调用之间使用ignore
:
std::cin >> userAmountSelection;
std::cin.ignore(); //---
...
for (int i = 0; i < userAmountSelection; i++)
...
getline (...);
...
getline (...)
此外,在某些情况下,您可能不知道std::cin
是否会在getline
之前。在这种情况下,您可以在执行ignore
之前检查输入流是否包含新行:
...
// some I/O operations happening here
...
// ignore if there's white space
if (std::iswspace(std::cin.peek())) std::cin.ignore();
std::getline(std::cin, somestring);
【讨论】:
以上是关于C++ --- getline 和 cin ignore () . 删除输出字符串中的第一个字符的主要内容,如果未能解决你的问题,请参考以下文章
C++ --- getline 和 cin ignore () . 删除输出字符串中的第一个字符
c++中 cincin.get()cin.getline()cin.getchar()的区别