Frage

While I'm in school and studying C++ this is not a question that is part of a homework assignment, just an oddity I came across and I'm wondering how to solve for myself and future reference.

Searching I didn't see anything that seemed to relate to this directly.

So I'm looking for input of type int, but I noticed when running a program that if a char input is received (not sure about string) that it is converted to int (I read in my textbook that this is normal C++ behavior).

My question is : how do I test for type char on input since it is automatically converted to int? I'm used to Python, Ruby, PHP, etc where there are usually some standard library methods for this, but in searching here and google there doesn't seem to be. Below is a stripped down version of what I was using when I discovered this problem.

I'm also wondering: What does C++ get the value for the char from? Is it the ASCII value or something else? If you run the code below and type in any single alphabet character you'll see what I'm talking about.

I've seen some solutions that included external libraries, but hoping there's something in the standard library/distribution of C++ to work this out with.

If this is related: my system is OS X 10.8 and running gcc.

Thanks!

#include<iostream>
using namespace std;

int main()
{
    int user_input;
    int n;

    cout << "Enter a number: ";
    cin >> user_input;

    for (n = 0; n < user_input; n++)
    {
        cout << n << endl;
    }

    cout << user_input << endl;

    return 0;
}
War es hilfreich?

Lösung

how do I test for type char on input

There are several mechanisms to use. You might consider these 2:


Style 1.
The 'c' style would be to check every input char with isdigit(). i.e. Read user input into a string, check that each char is a digit, etc.

std::cout << "Enter a number: ";
std::string user_input;
std::cin >> user_input;
for (int i=0; i<user_int.size(); i++
   if (!isdigit(user_input[i])
      throw "not a digit";
// if you get here, all the chars in user_input are digits, 
// I suppose you might use atoi()  to convert, but see next.

Note - there is also a hex check, isxdigit(). And if you want to allow the user to input commas or space chars, you can use user_input.erase(...) for each single char you wish to allow the user to use, but ignore as part of the number.


Style 2.

You may prefer the c++ style, which I find easier, but requires getting comfortable with C++ std::string methods.

std::cout << "Enter a number: ";
std::string user_input;
std::cin >> user_input;
const char* DIGITS = "0123456789";
size_t notaDigit = user_input.find_first_not_of(DIGITS);
if(notaDigit != std::string::npos)
   throw "non-digit char found in user_input";

// if you get here, all chars are digits, so convert to integer.
// these days, I would do this in 4 steps.
int user_int = 0;
{
   std::stringstream ss;
   ss << user_input; // put char string into ss
   ss >> user_int;   // extract and convert to integer 
} // discard and cleanup the stringstream at scope end

std::cout << "user_int: " << user_int << std::endl;

if a char input is received (not sure about string) that it is converted to int

FYI - I was unable to reproduce this on gcc 4.8.1 on ubuntu 12.04.

Character inputs thru std::cin do not convert to int.

The conversion attempt stops converting digit's into part of the integer at the first non-digit char. Thus, a 33Y will convert to 33, because it stopped converting at the Y. An ABC input, (or AB input, or A input,) will stop converting at the first (non-digit) char, thus the conversion reports 0.

I believe that that certain conversion attempts (from string to POD) can also set flags on the istream, but did not check.

Examples:

 dmoen@C5:~/cvs-tools/lmbm/src_ut$ ./dmy24
 Enter a number: 12
 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 dmoen@DOMA5:~/cvs-tools/lmbm/src_ut$ ./dmy24
 Enter a number: a 
 0
 dmoen@DOMA5:~/cvs-tools/lmbm/src_ut$ ./dmy24
 Enter a number: bcd
 0
 dmoen@DOMA5:~/cvs-tools/lmbm/src_ut$ ./dmy24
 Enter a number: ABC
 0

Note that most C-style functions automagically promote a char into an int. For example, the input to isdigit() is declared to be an int, so the promotion makes it easier to use.

C++ also supports this promotion, but I would guess that is not what you were seeing.

Andere Tipps

You should check for failed cins:

....
cin >> user_input;
if (cin.fail())
  cout << "Please enter numbers only" << endl;
else
{ // REST of your code }

AFAIK those values are arbitrary, and not corresponding to ASCII values or anything.

Try reading user_input as a c string and convert it to int using atoi.

That should help.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top