7

I'm having trouble with isdigit. I read the documentation, but when I cout << isdigit(9), I get a 0. Shouldn't I get a 1?

#include <iostream>
#include <cctype>
#include "Point.h"

int main()
{
    std::cout << isdigit(9) << isdigit(1.2) << isdigit('c');
    // create <int>i and <double>j Points
    Point<int> i(5, 4);
    Point<double> *j = new Point<double> (5.2, 3.3);

    // display i and j
    std::cout << "Point i (5, 4): " << i << '\n';
    std::cout << "Point j (5.2, 3.3): " << *j << '\n';

    // Note: need to use explicit declaration for classes
    Point<int> k;
    std::cout << "Enter Point data (e.g. number, enter, number, enter): " << '\n' 
        << "If data is valid for point, will print out new point. If not, will not "
        << "print out anything.";
    std::cin >> k;
    std::cout << k;

    delete j;
}
Crystal
  • 28,460
  • 62
  • 219
  • 393

3 Answers3

16

isdigit() is for testing whether a character is a digit character.

If you called it as isdigit('9'), it would return nonzero.

In the ASCII character set (which you are likely using), 9 represents the horizontal tab, which is not a digit.


Since you are using the I/O streams for input, you don't need to use isdigit() to validate the input. The extraction (i.e., the std::cin >> k) will fail if the data read from the stream is not valid, so if you are expecting to read an int and the user enters "asdf" then the extraction will fail.

If the extraction fails, then the fail bit on the stream will be set. You can test for this and handle the error:

std::cin >> k;
if (std::cin)
{ 
    // extraction succeeded; use the k
}
else
{
    // extraction failed; do error handling
}

Note that the extraction itself also returns the stream, so you can shorten the first two lines to be simply:

if (std::cin >> k)

and the result will be the same.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
5

isdigit() takes an int which is the representation of the character. Character 9 is (assuming you're using ASCII) the TAB character. Character 0x39 or '9' (not 9) is the actual character representing the digit 9.

The digit characters are integer codes 0x30 through 0x39 (or 48 through 57) in ASCII - I reiterate that since ASCII is not a requirement of the ISO C standard. Hence the following code:

if ((c >= 0x30) && (c <= 0x39))

which I've seen before, is not a good idea for portability since there is at least one implementation that uses EBCDIC under the covers - isdigit is the best option in all situations.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    +1 for noting the correct function signature, demonstrating the interchangability of `char` and `int`. – Steve Guidi Jun 03 '10 at 23:57
  • 3
    The standard does mandate however that the character value of digits must be sequential from 0 to 9. So, `if ((c >= '0') && (c <= '9'))` would work. The same is *not* true for alphabetic characters. – dreamlax Jun 04 '10 at 00:54
  • IIRC `isdigit('๑')` could also return true - char can also be a superset of ASCI. – MSalters Jun 04 '10 at 08:28
0

isdigit() works on characters, not ascii values, which you are currently passing. Try using isdigit('9').

Caleb Hearth
  • 3,315
  • 5
  • 30
  • 44
  • The function is `isdigit` (lowercase 'd'), arguably, `isdigit` may very well work on ASCII values. – dreamlax Jun 04 '10 at 00:46
  • Fixed that. It would work just fine on ASCII, but you'd have to know that you were using ASCII and not passing a character. I think he was trying to test '9' not `TAB` – Caleb Hearth Jun 04 '10 at 01:01