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

时间:2013-12-31 16:15:24

标签: c++

可能之前有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;
}

4 个答案:

答案 0 :(得分:5)

当您使用格式化的输入函数(即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))

答案 1 :(得分:4)

问题是,cin使用空格作为分隔符(也是制表符,换行符)。因此,您必须忽略分隔符来读取输入:

cin >> noskipws >> x;

或者对单个字符使用get

cin.get(x);

另请查看How to cin Space in c++?

答案 2 :(得分:3)

默认情况下,

cin会跳过所有空格(空格,制表符,换行符等)。您可以更改其行为,也可以使用稍微不同的机制。要更改其行为,请使用操纵器noskipws,如下所示:

char key;
cin >> noskipws >> key;

你可以在这里阅读更多相关信息“How to cin Space in c++?”。

答案 3 :(得分:1)

如何阅读空格字符。

替换它:

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 ++编译器的未定义行为,并且可能会在调试模式下崩溃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;
    }
}