为什么这个对isspace()的调用永远不会返回true



这可能以前被问过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;
}
}

相关内容

  • 没有找到相关文章

最新更新