这可能以前被问过100次,但我找不到或无法产生解决方案。一切(就我所测试的而言)都是公认的,只有紧迫的空间是不起作用的。我输入空格+回车键,光标移动到下一行,什么也没发生。我该怎么做?
#include <cstdlib>
#include <iostream>
#include <cctype>
using namespace std;
int main(int argc, char** argv) {
cout << "Press a key please: " << endl;
char key;
cin >> key;
if (isalpha(key))
cout << key << " is a letter." << endl;
else if (isdigit(key))
cout << key << " is a number." << endl;
else if (isspace(key))
cout << key << " is a space." << endl;
else if (ispunct(key))
cout << key << " is a punctuation" << endl;
return 0;
}
当您使用格式化的输入函数(即operator>>()
)时,默认情况下,输入将跳过前导空格。如果您想读取可能是空间的char
,则需要使用std::noskipws
操纵器禁用此跳过:
if (std::cin >> std::noskipws >> c) {
// ...
}
或者,您可以使用未格式化的输入函数,例如get()
,在不更改流设置的情况下读取单个字符:未格式化输入函数不会跳过前导空格(当在格式化输入(例如int
)和未格式化输入(如使用std::getline()
读取行)之间切换时,这通常会导致悲伤):
if (std::cin.get(c)) {
// ...
}
此外,请注意,您只能将正值(和EOF
)传递给任何is....()
函数,但char
在许多平台上都是签名的。您需要先将char
转换为合适的值,例如使用
isspace(static_cast<unsigned char>(c))
isspace(std::char_traits<char>::to_int_type(c))
问题是,cin
使用空白作为分隔符(还有制表符、换行符)。因此,您必须忽略分隔符来读取输入:
cin >> noskipws >> x;
或者对单个字符使用get
:
cin.get(x);
还可以看看如何在c++中创建空间?
cin
会跳过所有空白(空格、制表符、新行等)。您可以更改其行为,也可以使用稍微不同的机制。要更改其行为,请使用操纵器noskipws,如下所示:
char key;
cin >> noskipws >> key;
你可以在这里阅读更多关于这方面的内容"如何在c++中创建空间?"。
如何读取空格字符
替换此:
cin >> key;
跳过空白,将文本留在输入缓冲区中,如下所示:
auto const max_streamsize = numeric_limits<streamsize>::max();
key = char( cin.get() );
cin.ignore( max_streamsize, 'n' );
它不会跳过空白,并且会消耗所有的输入行。
不消耗所有输入行(例如终止的'n'
字符)的问题是,在不首先等待物理用户输入的情况下,下一个输入操作将读取剩余的文本。
如何使用C字符分类器函数
像isalpha
这样的C函数需要一个非负字符代码,或者特殊值EOF
作为参数。
然而,对于大多数C++编译器,默认情况下会对char
进行签名。通常,如果直接传递给例如isalpha
,则这意味着正式的未定义行为。例如,通过直接将char
值"ø"(挪威语小写æ)传递给isalpha
来检查其是否按字母顺序排列,这在大多数C++编译器中是"未定义行为",在Visual C++和其他一些编译器中可能会在调试模式下崩溃。
一个简单的解决方案是将其强制转换为unsigned char
(注意:不能通过这种方式传递EOF
):
typedef unsigned char UChar;
... isalpha( UChar( ch ) ) ...
完整的示例,如原始代码:
#include <iostream>
#include <limits> // std::numeric_limits
#include <ctype.h> // isalpha etc.
using namespace std;
auto main()
-> int
{
typedef unsigned char UChar;
auto const max_streamsize = numeric_limits<streamsize>::max();
for( ;; )
{
cout << "Type a character please (x to exit): ";
char const key = char( cin.get() );
cin.ignore( max_streamsize, 'n' );
if( key == 'x' ) { break; }
if( isalpha( UChar( key ) ) )
cout << key << " is a letter." << endl;
else if( isdigit( UChar( key ) ) )
cout << key << " is a number." << endl;
else if( isspace( UChar( key ) ) )
cout << key << " is a space." << endl;
else if( ispunct( UChar( key ) ) )
cout << key << " is a punctuation" << endl;
else
cout << key << " is some unknown kind of character" << endl;
}
}