8

I'm a python programmer getting to learn C from the K&R book. This will seem like an awfully trivial question, but I'm stumped nonetheless. Attached below is a snippet of code from the K&R (RIP Ritchie!) book which implements the atoi() function.

atoi(s) /*convert s to integer */
char s[];
{
    int i, n, sign;
    for (i=0; s[i]==' '||s[i] == '\n' || s[i] == '\t'; i++)
    ;   /* skip whitespace */
    sign = 1;
    if (s[i] == '+' || s[i] = '-')  /* sign */
        sign = (s[i++] == '+') ? 1 : -1;
    for (n=0; s[i] >= '0' && s[i] <= '9'; i++)
        n = 10 * n + s[i] - '0';
    return (sign * n);
}

My questions:

1) Does the first 'for' loop serve any purpose besides counting the number of valid characaters?
2) If (1) is true, the first loop sets the value of 'i' to the number of valid characters - how does the second for loop work without reseting i to 0?

Say for example I enter '2992' as an input to the function. The first for loop sets i to 3, so how does the rest of the function work? I may have my basics all messed up but any help would be really appreciated. Thanks, -Craig

Craig
  • 1,929
  • 5
  • 30
  • 51
  • 1
    I wasn't aware that C is _that_ terrible. – Patrick B. Oct 31 '11 at 17:56
  • I think that the best way to understand a piece of code is to execute it with a debugger (e.g gdb), and go forward step by step. Also reading the code and the comments inside may help. – eyalm Oct 31 '11 at 18:00
  • @PatrickB.: that's _very old_ C. Modern C looks... exactly the same :) (except for the function signature that is now the much clearer `int atoi(const char * s)`.) – Mat Oct 31 '11 at 18:12
  • In the 2nd edition of K&R, the function has a somewhat better (and more modern) style ... see here: http://codepad.org/U4hPr4Eg – pmg Oct 31 '11 at 18:13
  • @PatrickB. C is a cross platform assembler, and not much more...nothing mind-blowing in it by today's standards (other than the radical scope of its influence and usage). But don't confuse it with the likes of C++11, which is a profound paradigm-shifting beast for those who have the patience to learn it. – HostileFork says dont trust SE Oct 31 '11 at 18:17

6 Answers6

11
int atoi(char* str)
{
    if(!str)
        printf("Enter valid string");

    int number = 0;
    char* p = str;

    while((*p >= '0') && (*p <= '9'))
    {
        number = number * 10 + (*p - '0');
        p++;
    } 
    return number;
}

Here is the whole idea behind ATOI.

1) You set the pointer at the start of the char array

2) And then inside while loop you go over each character and multiply by 10 and add the character by subtracting by 0.

And if you will try with 2992. the number would be 2992 as well.

alice7
  • 3,834
  • 14
  • 64
  • 93
4

The first loop does what the comment says: it skips whitespace.

After it, i is the index of the first non-whitespace character, which is exactly what you need to proceed.

Mat
  • 202,337
  • 40
  • 393
  • 406
1

No, the first loop skips whitespace, like the comment says.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
1

The comment provides the answer: the first loop is to skip whitespace. For 2992, i will remain 0.

Nim
  • 33,299
  • 2
  • 62
  • 101
1

The first for loop advances i to point to the first non-whitespace character.

The conditional between the loops makes note of the sign, if any.

Then the final for loop does the actual conversion.

Finally, the sign is applied, and the result is returned.

Greg Jandl
  • 831
  • 9
  • 12
0

1) no first for loop does not count the number of character but it counts the first position of number if only starting chars are whitespaces i.e for this " -2992" i will be 1 and for "2992" i will be 0. 2) sign = (s[i++] == '+') ? 1 : -1; this statement checks if the i\'th char is a sign and makes the counter raise by 1[i++] and for the next for loop this i is the first starting digit in the string. if i makes 0 then for first conditional input your checking charter will be space!

edit1: first input is "space space-2992"

Atiqur
  • 81
  • 1
  • 2