我正在尝试在C ++中实现暂停功能,但它会永远循环。
我正在使用macOS,但是我试图创建一个在任何系统中都可以使用的暂停功能...我相信我的cin >>不能从键盘上捕获'\ n'或'\ r',并且它永远循环。
void Transferencia::pause() {
char enter = 0;
while(enter != '\n' && enter != '\r') {
cout << "(Press Enter to Continue...) ";
cin >> enter;
}
cin.clear();
}
Run Code Online (Sandbox Code Playgroud)
我想暂停程序,直到用户按下“输入”键。但是,即使我按“输入/返回”,它仍会循环播放...
在第一个:enter != '\n' || enter != '\r'是一个同义反复:即使enter 做的字符等于一个也不能等于另一个。因此,其中一个测试必须为真...如果两个值enter都不相等,则实际上您希望停留在循环中。
std::cin >> ...在按Enter键之前不会读取数据,但是它将丢弃换行符(实际上是所有空格)。因此只需要无循环地读取一个字符就足够了(循环又会得到一个无穷的循环);单独:如果用户在按“ enter”键之前根本不输入任何内容,则没有字符可读取std::cin,我们仍在等待。
您可以做的是阅读整行:
std::string s;
std::getline(std::cin, s);
Run Code Online (Sandbox Code Playgroud)
那也将接受空行,因此也正是您想要的(注意:没有循环!)。
编辑(从评论中窃取;感谢托马斯·马修斯):更为优雅的方法是
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Run Code Online (Sandbox Code Playgroud)
因为它不会创建任何其他资源(无论如何,该资源随后都将被丢弃std::string)。
编辑2:
根据上次输入操作的类型,可能仍会缓冲一个换行符(甚至更多的数据),例如之后int n; std::cin >> n;。在这种情况下,您需要跳过尚未缓冲的输入。因此,您将需要忽略两次。
但是,如果最后一个输入操作已经消耗了换行符(例如std::getline-或根本没有任何先前的输入操作),那么这将导致用户不得不按Enter键两次。因此,您需要检测之前发生了什么。
std::cin.rdbuf().in_avail()使您可以检测到还缓冲了多少个字符。因此,您可以:
if(std::cin.rdbuf().in_avail())
{
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "press enter" << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Run Code Online (Sandbox Code Playgroud)
但是,在某些系统(包括我的系统)上,in_avail即使尚未缓冲换行符,也可以返回0!std::cin.sync_with_stdio(false);可以解决问题;您应该在第一次输入操作之前执行它。希望你不要用C ++(流)和C( ,scanf,printf等),然后IO混合...
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |