June, 1998 Learning to C

Part 9: Reading Input

While programs can be designed to only output information, most of the time you will want to get information from the user. There are many ways to receive input from the user in a C program. No one way is either right or wrong, and each way comes with its own advantages, disadvantages and restrictions. Also you are not limited to using only one manner in your program but can use any combination as you prefer.

One of the simplest methods to receive input from the user is to use the getchar() function. This function stops the program and waits until it receives a character entered on the keyboard followed by the Enter key. Until the user hits the Enter key the program will not continue to execute. The getchar() function requires no arguments in the parenthesis and returns a character variable which can be stored and used. Here is an example:

/* getchar.c 1.0 (06/28/98) */
#include <stdio.h>

int main(int argc, char *argv[])
{
   char input_character;

   printf("Enter a character : ");
   input_character = getchar();
   printf("You entered the character %c !\n", input_character);
   return 0;
}

The variable input_character is declared and set to hold a character type variable. It is best to always inform the user that you are requesting they enter something, and also what exactly you expect them to enter. That is the purpose of the first printf() function which displays a prompt requesting that the user enter a character. While you may know what the program is expecting, every other user who runs your program will not, so the prompt tells them they need to enter something and what they need to enter.

The line following the first printf() tells the program to use the getchar() function to read a character from the keyboard, then store it in the variable input_character. The user can type as many characters as they want and the program will sit there until they press the Enter key. As soon as Enter is pressed the program will continue, storing the first character entered in the variable input_character.

The last line displays the character that the user entered. The %c place holder in the printf() function is used for displaying characters and is replaced with the variable input_character when the program runs.

While not useful to everyone, and not part of the ANSI C standard, most MS-DOS C language compilers, and a few others, like SAS/C for the Amiga, come with a special function called getch() which allows a character to be entered without having to press the Enter key afterwards. This function works like getchar(), returning a character and requiring no arguments, but as soon as the first character key is pressed, the program continues. The getch() function requires you to include the conio.h header file for MS-DOS C compilers.

Another difference when using the getch() function is that the character pressed is not displayed on the screen. The function getche() is the same as the getch() function, but it displays or echoes the character pressed on the screen. It is also not available with all compilers and is not part of the ANSI C specification. Here is a simple example:

/* getchar.c 2.0 (06/28/98) */
#include <stdio.h>
#include <conio.h> /* this line is only for MS-DOS compilers */

int main(int argc, char *argv[])
{
   char input_character;

   printf("Enter a character : ");
   input_character = getch();
   printf("You entered the character %c !\n", input_character);
   printf("Enter another character : ");
   input_character = getche();
   printf("You entered the character %c !\n", input_character);
   return 0;
}

The first character you enter when you run the program won't be displayed when you enter it, but the second one should be.

While reading in a single character can answer a yes or no question with a Y or N, it can't easily be used to input a name or address. That is where the gets() function comes in. The gets() function is used to read in a complete string from the keyboard. It stores the string entered in a character array argument you give it using the name or identifier of the array, since the identifier is a pointer to the memory address of the array as discussed in the last article.

/* getstring.c 1.0 (06/28/98) */
#include <stdio.h>

int main(int argc, char *argv[])
{
   char first_name[25];

   printf("Enter your first name : ");
   gets(first_name);
   printf("Pleased to meet you %s!\n",first_name);
   return 0;
}

The program declares an array of 25 characters called first_name to store the entered string. Always be sure to have your arrays 1 character larger than you need since a string of characters always ends with an additional NULL or \0 character. The first printf() displays the prompt, telling the user what to enter. The program then sits there as the user types in characters until the user hits the Enter key ending the string which is then stored in the array first_name.

After reading in the string of characters and storing them in the first_name array, the program displays the string to the screen using printf().

While gets() is useful for reading in a string of characters, what if you wanted to read in a number? When the gets() function reads in the string and stores it in the character array, it is stored in memory as the ASCII character values. To convert this string into an integer that you can use for arithmetic, you would use the atoi() function.

The atoi() function converts ASCII characters into an integer which is where it gets its name. It requires a string pointer as its argument and returns the integer value of that string. If the string contains no numbers the atoi() function returns the value 0. In order to use the atoi() function you have to include the stdlib.h header file.

Here is an example using atoi():

/* getint.c 1.0 (06/28/98) */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
   char input_string[10];
   int input_integer;

   printf("Enter a number : ");
   gets(input_string);
   input_integer = atoi(input_string);
   printf("You entered the number %d.\n", input_integer);
   return 0;
}

First the program declares a character array to store the string which will be received and the integer to store the converted string. The program displays the prompt using printf() then pulls in the string using gets(). The string is converted to an integer using atoi() and stored in the integer variable then displayed using printf().

This next section is a little more advanced and is not required knowledge to use the C language, but it will help you decipher other C programs and save you time when you learn to use it. The gets() function not only stores the string given by the user in the argument sent to it, but also returns a character array pointer for the string. The atoi() function requires a string as an argument. You can use the gets() function directly in the atoi() function and you won't have to have storage for the string or write as many statements.

/* getint.c 2.0 (06/28/98) */
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
   int input_integer;

   printf("Enter a number : ");
   input_integer = atoi(gets());
   printf("You entered the number %d.\n", input_integer);
   return 0;
}

What the C program does is run the functions from the inside out. First it pulls in the string with the gets() function, then uses the string which is returned by the gets() function as the argument for the atoi() function. Then it stores the resulting integer in the integer variable. If you were only going to display the number once instead of using the variable in a arithmetic operation, you don't even need to store the resulting integer in a variable and can put the atoi() function directly into the printf() function, like this:

/* getint.c 3.0 (06/28/98) */
#include <stdio.h
#include <stdlib.h>

int main(int argc, char *argv[])
{
   printf("Enter a number : ");
   printf("You entered the number %d.\n", atoi( gets() ) );
   return 0;
}

While this version of the program looks far more cryptic, it performs exactly the same as the previous two versions. If you needed to use the variable entered again later you would want to store it in a variable and not use it in this manner. If all you are doing is displaying the number right after you enter it, this version works fine, saves memory and may even run faster on your computer depending on the capabilities of your compiler.

Optimization like this is not required, and it can make the program code much harder to read, but knowing that it is possible, and how it is possible, will allow you to use it when you need to and also be able to read another person's programs when they use it.

Another function used to read in input is scanf(). The scanf() function's arguments are similar to the printf() function, using a format string then the names of the variables. The scanf() function returns the total number of characters read in, but you do not need to make use of this variable if you don't want to. While the scanf() function can read in other types of variables besides text strings, it is not always wise to use it in this manner. The reasons for this will be explained in a moment, but first here is an example of using scanf() to read in a text string:

/* getstring.c 2.0 (06/28/98) */
#include <stdio.h>

int main(int argc, char *argv[])
{
   char first_name[25];
   int name_length;

   printf("Enter your first name : ");
   name_length = scanf("%s", first_name);
   printf("Pleased to meet you %s! Your first name is %d characters long.\n",first_name, name_length);
   return 0;
}

The %s placeholder in the format string argument tells the scanf() function that it is reading in a string of characters, and first_name tells scanf() the memory address where to store that string. Don't forget that the name of the character array by itself is a pointer to the memory address of the first element in that array. After scanf() reads in the characters it returns the number of characters read and stores them in the variable name_length. If you have no need to know the number of characters read in with the scanf() function you can just leave off that part, like in the next example.

Here is an example using scanf() to read in a string and an integer:

/* getmore.c 1.0 (06/28/98) */
#include <stdio.h>

int main(int argc, char *argv[])
{
   char first_name[25];
   int age;

   printf("Enter your first name and age : ");
   scanf("%s %i", first_name, &age);
   printf("Pleased to meet you %s! You are %i years old.\n",first_name, age);
   return 0;
}

The format string argument in the scanf() function tells the function that it will be reading in a character string and an integer. Again first_name is the memory pointer to the location that scanf() will store the character string. With the age variable you have to use the & symbol to tell scanf() the memory address of the age variable so it can store the integer that it reads in. This was not required with first_name since first_name is a pointer to the memory address of the first_name[] array of characters.

While this program works fine when the user enters the correct information, if the user enters the information incorrectly problems will occur. After typing in a character string for the first_name variable, if the user types a character instead of integer the program will error or crash. The information has to be entered correctly, but there is no way to make sure this will happen every time.

What is most commonly done is to always read in character strings, and if you are trying to get a number from the user you can convert the string to an integer using the atoi() function. This way no matter what the user enters, the program will not crash. Of course remember that if you use the atoi() function on a string that does not contain any numbers, it will return the value 0.

You can use any or all of these functions in your programs to read in information from the user of the program. Always be sure to remember the requirements and limitations of each function so that you can use it properly, and be sure to check for errors in the input since you can never know just what a user has entered without checking it after it has already been done. If you are asking for an integer and a string is entered, verify the input and ask again until the user gets it correct.