質問

I'm experiencing a very odd issue with atoi(char *). I'm trying to convert a char into it's numerical representation (I know that it is a number), which works perfectly fine 98.04% of the time, but it will give me a random value the other 1.96% of the time.

Here is the code I am using to test it:

int increment = 0, repetitions = 10000000;
for(int i = 0; i < repetitions; i++)
{
    char randomNumber = (char)rand()%10 + 48;
    int firstAtoi = atoi(&randomNumber);
    int secondAtoi = atoi(&randomNumber);
    if(firstAtoi != secondAtoi)NSLog(@"First: %d - Second: %d", firstAtoi, secondAtoi);
    if(firstAtoi > 9 || firstAtoi < 0)
    {
        increment++;
        NSLog(@"First Atoi: %d", firstAtoi);
    }
}
NSLog(@"Ratio Percentage: %.2f", 100.0f * (float)increment/(float)repetitions);

I'm using the GNU99 C Language Dialect in XCode 4.6.1. The first if (for when the first number does not equal the second) never logs, so the two atoi's return the same result every time, however, the results are different every time. The "incorrect results" seemingly range from -1000 up to 10000. I haven't seen any above 9999 or any below -999.

Please let me know what I am doing wrong.


EDIT:

I have now changed the character design to:

char numberChar = (char)rand()%10 + 48;
char randomNumber[2];
randomNumber[0] = numberChar;
randomNumber[1] = 0;

However, I am using:

MAX(MIN((int)(myCharacter - '0'), 9), 0)

to get the integer value.

I really appreciate all of the answers!

役に立ちましたか?

解決

atoi expects a string. You have not given it a string, you have given it a single char. A string is defined as some number of characters ended by the null character. You are invoking UB.

From the docs:

If str does not point to a valid C-string, or if the converted value would be out of the range of values representable by an int, it causes undefined behavior.

Want to "convert" a character to its integral representation? Don't overcomplicate things;

int x = some_char;

A char is an integer already, not a string. Don't think of a single char as text.

他のヒント

If I'm not mistaken, atoi expects a null-terminated string (see the documentation here).

You're passing in a single stack-based value, which does not have to be null-terminated. I'm extremely surprised it's even getting it right: it could be reading off hundreds of garbage numbers into eternity, if it never finds a null-terminator. If you just want to get the number of a single char (as in, the numeric value of the char's human-readable representation), why don't you just do int numeric = randomNumber - 48 ?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top