How to read a space character.
Replace this:
cin >> key;
which skips whitespace and leaves text in the input buffer, with this:
auto const max_streamsize = numeric_limits<streamsize>::max();
key = char( cin.get() );
cin.ignore( max_streamsize, '\n' );
which doesn't skip whitespace, and consumes all of the input line.
The problem with not consuming all of an input line, such as the terminating '\n'
character, is that this remaining text will then be read by the next input operation, without first waiting for physical user input.
How to use the C character classifier functions.
The C functions such as isalpha
require a non-negative character code, or else the special value EOF
, as argument.
With most C++ compilers the char
is, however, signed by default. In general that means formal Undefined Behavior if it's passed directly to e.g. isalpha
. For example, checking whether a char
value 'ø' (Norwegian lowercase Ø) is alphabetical, by passing it straight to isalpha
, is Undefined Behavior with most C++ compilers, and may crash in debug mode with Visual C++ and some other compilers.
A simple solution is to cast it to unsigned char
(note: cannot pass EOF
this way):
typedef unsigned char UChar;
... isalpha( UChar( ch ) ) ...
Complete example, like the original code:
#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;
}
}