melkimx
melkimx

Reputation: 23

getchar vs scanf: why won't getchar work?

I wrote a simple program to input a number and return any value which when divided by it will return a remainder of 3.

I'm currently reading K&R and it doesn't teach scanf until something like Chapter 7 so I tried to use getchar. It doesn't work, but scanf does. What am I doing wrong?

int main()
{
    int c, i;

    printf("Input an integer: ");
    //c = getchar();
    scanf("%d", &c);

    for (i = 1; i <= 100; i++) {
        if ((i % c) == 3) {
            printf("%d\n", i);
        }
    }
    return 0;
}

Optional side question: It seems like people here have been advising not to start with K&R. What might be a better alternative for a beginner?

Upvotes: 1

Views: 382

Answers (2)

Marco Bonelli
Marco Bonelli

Reputation: 69326

This:

scanf("%d", &c);

Is requesting scanf() to read an integer value from standard input. The scanf() function will read from standard input as much characters as needed, and then parse them into an integer, storing the value in the variable c (i.e. at the address pointed by &c). The return value of scanf() also communicates the number of correctly parsed items, so in this case you should check if the returned value is 1.

This:

c = getchar();

Is requesting getchar() to read a single character from standard input. The getchar() function will try to read a character, and will return it (casted to an int) in case of success. In case of error or end of file, the special integer value EOF will be returned. The fact that getchar() returns an int doesn't mean that the function will parse the input like scanf("%d", ...) does. Indeed, the return value has type int only because it's needed to distinguish a valid character from EOF.

To know more, refer to the manual pages for scanf and getchar using the man command, e.g. man scanf. Consulting manual pages is important to understand the semantics of a function. Always read the manual. Alternatively, you can look it up online: scanf(), getchar().


If you want to scan a single character using getchar() and convert it into an integer, then you can do the following:

#include <stdio.h>  // getchar(), puts()
#include <ctypes.h> // isdigit()

int main(void) }
    int c;

    c = getchar();
    if (c == EOF) {
        puts("Error!");
        return 1;
    }

    if (!isdigit(c)) {
        puts("Character is not a digit!");
        return 1;
    }

    int value = c - '0';
    // value now holds the integer corresponding to the digit that was read from input

    /* ... */

    return 0;
}

Note: c - '0' works because characters representing digits have sequentially increasing values in the ASCII table (from 0x30 to 0x39). See also man ascii.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310970

getchar reads one symbol from the inputs stream and returns it as its integer value of its internal representation or EOF.

So to read a number that has at least two digits you have to call getchar several times and then convert the symbols' representations to the corresponding integer number.

Opposite to getchar scanf tries to read a whole number as an integer if you specified the conversion format %d or similar specially designed to read numbers

Here is a demonstrative program that shows how your program can be implemented using getchar. In the program there is no check whether the user entered a too big number. You can add such a check yourself.

#include <stdio.h>
#include <ctype.h>

int main(void) 
{
    const unsigned int REMAINDER = 3;

    printf( "Input a non-negative integer: " );

    unsigned int n = 0;

    for ( int c; ( c = getchar() ) != EOF && isdigit( ( unsigned char )c ); )
    {
        const unsigned int Base = 10;

        n = Base * n + ( c - '0' );
    }


    if ( n > REMAINDER )
    {
        const unsigned int N = 100;
        for ( unsigned int i = 0; i < N; i++ )
        {
            if ( ( i + 1 ) % n == REMAINDER ) printf( "%u ", i + 1 );
        }
        putchar( '\n' );
    }

    return 0;
}

The program output might look for example like

Input a non-negative integer: 10
3 13 23 33 43 53 63 73 83 93 

As for books then it is always difficult to read a book on a language or technology which you are not familiar yet.

Upvotes: 0

Related Questions