Вероятно, это спрашивается 100 раз раньше, но я не могу найти или создать решение. Все (насколько я проверял) распознается, только нажатие пробела не работает. Я набираю пробел + hit enter, курсор просто переходит к следующей строке, и ничего не происходит. Как я могу сделать эту работу?
#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;
}
Проблема в том, что cin
использует пробел как разделитель (также tab, newline). Поэтому вы должны прочитать свой вход, игнорируя разделитель:
cin >> noskipws >> x;
В качестве альтернативы используйте get
для одиночных символов:
cin.get(x);
Также посмотрите, как cin Space в c++?
cin.get(key) >> key;
но это не вычислило.
Когда вы используете форматированные функции ввода (т.е. 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))
is*()
, но это не умаляет вашей точки зрения, что аргумент должен быть значением int
для представления unsigned char
(или EOF).
cin
пропускает все пробелы (пробелы, вкладки, новые строки и т.д.) по умолчанию. Вы можете либо изменить свое поведение, либо использовать несколько иной механизм. Чтобы изменить свое поведение, используйте манипулятор noskipws следующим образом:
char key;
cin >> noskipws >> key;
Подробнее об этом вы можете прочитать здесь " Как cin Space в c++? ".
Замените это:
cin >> key;
который пропускает пробелы и оставляет текст во входном буфере, при этом:
auto const max_streamsize = numeric_limits<streamsize>::max();
key = char( cin.get() );
cin.ignore( max_streamsize, '\n' );
который не пропускает пробелы и потребляет всю входную строку.
Проблема, заключающаяся в том, что вы не потребляете всю строку ввода, такую как завершающий символ '\n'
, заключается в том, что этот оставшийся текст будет затем прочитан следующей операцией ввода без предварительного ожидания ввода физического пользователя.
Функции C, такие как isalpha
требуют неотрицательного символьного кода или специального значения EOF
качестве аргумента.
Однако с большинством C++ компиляторов char
по умолчанию подписан. В общем, это означает формальное неопределенное поведение, если оно передается непосредственно, например, isalpha
. Например, проверяя, является ли значение char
"ø" (норвежский нижний регистр Ø) алфавитным, передавая его прямо на isalpha
, является Undefined Behavior с большинством 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;
}
}
key
когда вы нажимаете пробел?