GIDNetwork > Things to Avoid in C/C++ -- scanf, Part 5
Register
« Things to Avoid in C/C++ -- system("pause"), Part 4 Things to Avoid in C/C++ -- scanf / character, Part 6 »

Things to Avoid in C/C++ -- scanf, Part 5

by: WaltP - Sep 21, 2005

scanf()

Man, where to begin? scanf() is a notoriously ill-behaved function.

Half the time it leaves stuff in the input buffer to mess up your next input. If it finds an error in the input stream, it ungraciously leaves the offensive character for the next read. Now, to be fair, the problems we have with this function is usually through:

  1. lack of knowledge

  2. misuse

  3. overly complex format strings

rather than errors in the coding of the function itself. But the function is so complex that to a new programmer (and probably most veterans) this function is an enigma.

scanf() is a Jack of all trades function. It has been designed to handle as many input types as possible, from simple characters to scientific notation and complex values. And because of this, the design seems lacking in some areas.

I don't know the key to success, but the key to failure is trying to please everybody. -- Bill Cosby

That's how I feel about scanf().

Admittedly, I've never studied the scanf() fully. I've seen some of the format parameters that have been suggested to alleviate a few of the problems, and they are daunting to say the least. So where do you use this function? First and foremost, do not use it for characters and strings. The next two topics explain why. As for numbers, it doesn't really do too bad, and I'll explore that also.

But lack of knowledge is what gets most programmers. They want to read a character from the keyboard so they very logically use the format string "%c". Then wonder why the next read is messed up. How are they supposed to know that after the character was read there was a \n left behind? I've rarely (never?) seen documentation explaining that fact, but through experimentation and logical thinking (and a good debugger), one can in fact figure out what's happening.

Another problem is that new programmers tend to use this swiss army knife when a simple spoon would suffice. scanf() is a huge function! What scanf() has to do to work is:

  1. start parsing the format string

  2. look for a %

  3. figure out all the attributes in the format designator (%7.3lf for example)

  4. read the characters from the keyboard buffer until a character that isn't right for the format is found

  5. convert these characters into the proper binary format

  6. load the binary into the designated parameter following the format string

  7. continue again at step 2 until done.

That is a lot of work! Keep these steps handy as we continue through this exploration of scanf() function. They will come up again. I will simply refer to them as The Steps.

To examine the size of the scanf() function, I built the following programs to check the executable sizes.

Basic empty program:

  • C/CPP/C++ Code Example:

    #include <stdio.h>
    int main()
    {
        char c;
        return 0;
    }
  • Turbo C++ 1.0: 6,177 bytes

  • Borland C++ 5.5: 47,104 bytes

  • Visual C++ 6.0: 151,611 bytes

Character input with getchar() (my preferred function)

  • C/CPP/C++ Code Example:

    #include <stdio.h>
    int main()
    {
        char c;
        c = getchar();    
        return 0;
    }
  • Turbo C++ 1.0: 7,197 bytes (1020 extra bytes, 16% larger)

  • Borland C++ 5.5: 48,128 bytes (1024 extra bytes, 2% larger)

  • Visual C++ 6.0: 155,707 bytes (4096 extra bytes, 3% larger)

Character input with scanf()

  • C/CPP/C++ Code Example:

    #include <stdio.h>
    int main()
    {
        char c;
        scanf("%c", &c);    
        return 0;
    }
  • Turbo C++ 1.0: 9560 bytes ( 3383 extra bytes, 55% larger)

  • Borland C++ 5.5: 61,952 bytes (14848 extra bytes, 32% larger)

  • Visual C++ 6.0: 163,899 bytes (12288 extra bytes, 8% larger)

So as you can see, there is a lot of overhead having functionality you don't need, especially when reading a single character. This will be the topic of scanf()/character.

So stay tuned...

Would you like to comment? This story has been viewed 211,586 times.
« Things to Avoid in C/C++ -- system("pause"), Part 4 Things to Avoid in C/C++ -- scanf / character, Part 6 »

__top__

Copyright © GIDNetwork™ 2001 - 2024

Another website by J de Silva

Page generated in : 0.00922 sec.