![]() |
||||
|
||||
|
« Things to Avoid in C/C++ -- scanf / number, Part 8 | Beginning Python Tutorial (Part 5) » |
Things to Avoid in C/C++ -- scanf / epilogue, Part 9
by: WaltP - Oct 01, 2005
scanf() / So what's a programmer to do?scanf() is not designed for production code, but for creating test programs to see if other aspects of the program are working. scanf() will replace the complicated input routines so that other modules can be exercised and perfected. Then the scanf() is replaced with the real input function that gets the actual data from a file, a device, wherever the actual data is stored. And if that data is in fact from a user, the input modules will probably consist of a suite of routines that parse bits and pieces of the actual input string (read by fgets() probably) and can handle all different kinds of user errors without crashing or looping. When reading anything, scanf() will skip all leading whitespace. Then it grabs all the characters that fit the format specified. At the first invalid character it stops, leaving this character for the next read. For strings, invalid characters are all whitespace, defined as the following: Generic Code Example: Hex Dec Ctrl Name 0x09 9 ^I Tab 0x0A 10 ^J Line Feed 0x0B 11 ^K Verticle Feed 0x0C 12 ^L Form Feed 0x0D 13 ^M Carriage Return 0x1A 26 ^Z End of File 0x20 32 Space The character input is the main offender, since it reads any character that's available. Therefore, after reading anything with scanf(), following it with a single character read will always read whatever is left, and not what you were hoping to type in. So...
So, reading numbers is OK, reading a word works, but sentences don't. And attempting to read characters is just asking for trouble without a special function. Here is a function you can use to read a single non-whitespace character. This would be used in place of scanf("%c", &ch) to make sure you actually get to input the value: C/CPP/C++ Code Example: int getCharacter() { int ch; // define the character do // loop until a good character is read { ch = getchar(); // read a character } while ( (ch == 0x20) || // check for SPACE ((ch >= 0x09) && // check for the (ch <= 0x0D)) // other whitespace ); return ch; } This will keep reading until there is a non-whitespace character entered, effectively clearing the buffer from previous scanf() calls. This function will accept only printable non-whitespace (a more usable function): C/CPP/C++ Code Example: int getCharacter() { int ch; // define the character do // loop until a good character is read { ch = getchar(); // read a character } while ((ch <= 0x20) || // check above SPACE (ch >= 0x7F) // check below the last ); // ASCII char return ch; } So now you have no excuse for complaining Bottom line -- try to avoid it except in testing. And definitely avoid it when reading characters. caveat:
|
GIDNetwork Sites
Archives
Recent GIDBlog Posts
Recent GIDForums Posts
Contact Us
|
« Things to Avoid in C/C++ -- scanf / number, Part 8 | Beginning Python Tutorial (Part 5) » |