Console input

Reading a character

Let us start with the simplest function from the C Standard Library to read from the console. The function which header is int getchar() allows us to read one character from the console. It returns the ASCII value of the character read from the console, as a value of type int. In case of error, it returns the value of the macro EOF.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h> int main() { // Retrieves one character from the console. char c = getchar(); // Prints the character we read earlier. putchar(c); return 0; }

Even if we write many characters in the console and press the key enter, the function getchar only returns the first character entered. However, the other characters are not discarded. They are going to be retrieved by the following reading operations. That is possible because they are saved in a buffer (We will learn more about that later when we read about buffered streams).

Reading a string from the console

The function gets, which header is char* gets(char* str), is used to read a string of characters, from the console, into the pointer to an array of char received in argument (Until the newline character is reached. By the way, pressing enter in the console has the effect to enter the newline character). In case of error, it returns a null pointer (The address 0). Otherwise, it returns back the argument (The pointer to the character array). Note that even though it reads until it reaches the newline character, it does not write it to the string pointed in argument.

Warning: That function has been removed from the C Standard Library since the 2011 version of the specification of the C language (C11). The reason is that since the function is not aware of the size of the array pointed by its argument, it might overflow the array when writing to it the characters read. We should use, instead, scanf or the function fgets with stdin as argument (We will learn about that later).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h> int main() { /* Define the array of char that will receive the characters read from the console (And the value 0 at the end of it, because in C, we work with null-terminated strings). So the maximum amount of character it can receive is, it that case, 50 (The 0 at the end included). If it receives more, the program might either crash or behave in an unexpected way (Array overflow). */ char string[50]; // Reads the string from the console into the array of char. gets(string); // Prints the string we read. puts(string); return 0; }

Reading formatted data from the console

The function scanf, which header is int scanf(const char* format, ...), is the input equivalent of printf. The first argument is a string containing the specifiers which represent the types of data to read (And optionally how to read them) and the following arguments are pointers to the variables to which the function will write the data read. It returns the number of elements successfully read.

A specifier is written with the following template:

%[*][nbChar][argType]specifier

Elements shown between brackets are optional and are called sub-specifiers. If the asterisk * is written, it tells the function to read the data but to also discard it (Will not write it to the variable pointed by the argument, so it does not expect scanf to have an additional argument for it). The sub-specifier nbChar is used to specify the maximum amount of character to read. Depending on the specifier, scanf expects, by default, in argument, a pointer of a specific type. For example, if the specifier is d, it expects the argument to be a pointer of type int. The sub-specifier argType is used to change the expected type. For example, when the sub-specifier argType is l and the specifier is d, the expected argument becomes a pointer to a variable of type long.

Here is a table with the specifiers:

SpecifierDescription
cReads a character. If the sub-specifier nbChar is set, the number of characters specified by it will be read. It does not append a null character at the end of the array it writes the data to.
sReads a string until a whitespace character is reached (Space, tabulation, newline...). A null character is added at the end of the array the string is written to.
dReads a decimal integer.
iReads an integer. By default, it is considered to be a decimal integer. If the number is prefixed by 0, it is read as an octal number. If the number is prefixed by 0x or 0X, it is read as a hexadecimal number.
uLike the specifier i, but it reads an unsigned integer.
xReads a hexadecimal integer (Optionally prefixed by either 0x or 0X).
oReads an octal integer.
f, e, g, aReads a decimal floating point number. If the number is prefixed by 0x or 0X, it is read as a hexadecimal number.
[...]Reads characters as long as the character read is part of the characters defined inside the brackets. A null character is added at the end of the array the string is written to.
[^...]Reads characters as long as the character read is not part of the characters defined inside the brackets. A null character is added at the end of the array the string is written to. Note that when a character from those inside the bracket is reached, it is not read and therefore it stays in the buffer for the next input operation to read.
nThe number of characters read so far is stored in the variable pointed by the argument. Does not read anything from the console.

Here is a table with the argument types expected depending on the value of the sub-specifier argType:

argTypec, s, [..], [^..]d, iu, o, xf, e, g, apn
(Default)char*int*unsigned*float*void**int*
hhchar*unsigned char*char*
hshort*unsigned short*short*
lwchar_t*long*unsigned long*double*long*
lllong long*unsigned long long*long long*
jintmax_t*uintmax_t*intmax_t*
zsize_t*size_t*size_t*
tptrdiff_t*ptrdiff_t*ptrdiff_t*
Ldouble long*

Here is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h> int main() { int a; // Reads an integer from the console into a. scanf("%d", &a); // Prints the integer read to the console. printf("%d\n", a); float b; // Reads a floating-point number from the console, into the variable, of type float, b. scanf("%f", &b); // Prints the number read to the console. printf("%f\n", b); double c; // Reads a floating-point number from the console, into the variable, of type double, c. scanf("%lf", &c); // Prints the number read to the console. printf("%f\n", c); char str[51]; /* Reads a string of character from the console (Until a white space is reached (Space, newline, tabulation...)) into the array str. No more than 50 characters can be read. */ scanf("%50s", str); // Prints the null-terminated string contained inside the array str, to the console. printf(str); puts(""); // Prints a newline character. /* Reads a string of character from the console (Until a white space is reached (Space, newline, tabulation...)), but it discards it. No more than 50 characters can be read. */ scanf("%*50s"); return 0; }

Here is an other example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h> int main() { char str2[41]; /* Reads a string of character from the console (Until a newline character is reached) into the array str2. Note that the newline character is not read from the console, so it stays there. */ scanf("%40[^\n]", str2); /* Prints the null-terminated string contained inside the array str2, followed by a newline character, to the console. */ puts(str2); /* If the user entered more than 40 characters, the additional characters will stay in the buffer for the next input operation to retrieve. The following line is used to read and discard them: */ scanf("%*[^\n]"); /* The last input operations left a newline character in the buffer. The next line is used to retrieve it and discard it, so the next input operations do not receive it. */ scanf("%*1[\n]"); int d; float e; /* Reads an integer, from the console, into the variable d and then reads a floating point number from the console into e. */ scanf("%d%f", &d, &e); /* Writes the values of d and e into the console. */ printf("%d %f\n", d, e); return 0; }

Note that the console only display and input text, so when we read a number from it, the function scanf converts the string read to a number of the specified type. It is perfectly possible to simply read strings from the console and manually convert them.