简体   繁体   中英

C incrementing a variable inside a function that's inside the while conditional

I've implemented atoi function. The first while conditional gives wrong answers while the second while conditional gives me the correct answer (provided I increment the pointer inside the while block ofcourse)

while( isdigit(*(str++)) )
while( isdigit(*str) )

Why is that?

Shouldn't the first while conditional evaluate 'str' then increment. Then dereference the evaluated address. Then pass it to isdigit?!

Isn't that the same as the second while conditional(as long as it's incremented inside the loop)?

Here's the full code just in case:

int atoi(char *str)
{
    int sign, number = 0;

    while( isspace(*str) )
        ++str;

    sign = (*str == '-') ? -1 : 1;

    if(*str == '-' || *str == '+')
        str++;

    //while( isdigit(*(str++)) )
    while( isdigit(*str) )
    {
        number = 10 * number + (*str - '0');
        str++;
    }
    return sign * number;
}

Anatomy of the error: isdigit(*str++) tells you if the character pointed at by str is a digit, so you decide to iterate the loop to process the character — but ++ advances the pointer before you enter the loop's body, so you process the next character.

Additionally, as @iharob points out in the comment below, str is incremented despite the isdigit result, also when the character is not a digit. So the first non-digit character would not be processed by the following code (if there were any).

Potentially same problem with while(isspace(...)) .

The problem isn't with the while (isdigit(*str++)) but the fact that at this line

number = 10 * number + (*str - '0');

str is pointing to the next character because you already incremented str in the while condition.

That's why you can't increment the pointer in the while condition. You can however do it in the assignment, leading to the following loop

while (isdigit((unsigned char) *str) != 0)
    number = 10 * number + (*str++ - '0');

This is an example of a possible implementation

#include <ctype.h>

int my_atoi(const char *str)
{
    int sign;
    int number;

    number = 0;

    while (isspace((unsigned char) *str) != 0)
        ++str;

    sign = 1;
    switch (*str)
    {
        case '-':
            sign = -1;
        case '+':
            str++;
            break;
    }

    while (isdigit((unsigned char) *str) != 0)
        number = 10 * number + (*str++ - '0');

    return sign * number;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM