For data input and output, C provides a collection of library functions such as getchar, putchar, scanf, printf, gets and puts. These functions enable the transfer of data between the C program and standard input/output devices. C always treats all input-output data, regardless of where they originate or where they go, as a stream of characters. The operating system makes the input and output devices available to a C program as if these devices were files. So, essentially, when a C program reads data from the keyboard, it is in effect reading from the file associated with the keyboard device. When a C program sends output data to the console, it is in effect writing to the file associated with the console device.
A stream of characters or text stream, is a sequence of characters divided into lines. Each line consists of various characters followed by a newline character (\n). All input-output functions in C conform to this model.
The standard input-output devices or the associated files or text streams, are referred as -
In order to be able to use the above mentioned input-output functions in your C program, you must begin each C program with a pre-processor directive to include these standard library functions.
This can be done with a line entry - #include <stdio.h>
.
The input-output functions, fall into two categories - formatted read/write functions and non-formatted read/write functions. We will take up the easier one first, viz. the non-formatted read/write functions.
This is a single character input function. getchar() reads a single character from stdin - the standard input data stream, viz. the file associated with the standard input device, which is normally the keyboard.
Note that when you input a single character for the C program to read, you must indicate end of data stream or end of input by pressing the return/enter key after entering your response character. When you simply press the enter key without inputting any value first, the getchar function will return the symbolic constant EOF (for end of file) which typically stores the value -1, when there is no input. The EOF is an integer constant defined in stdio.h header file.
This is a single character output function. putchar() writes a single character to stdout - the standard output data stream, viz. the file associated with the standard output device, which is normally the console.
Note that in the above example code, you can declare the variable c either as a char or as an int, since in C, a single character is internally represented as it's corresponding numeric ASCII code.
The standard library function gets accepts input in the form of a string. The character string may even include whitespace characters. Each call to gets will read all the characters from the input steam until an end of line character is encountered. The end of line character is represented as \n and gets generated when you press the enter key. gets assigns the read string to the variable that is passed as its parameters. gets assigns NULL when an error occurs.
The standard library function puts sends the passed string to stdout. After the output, puts sends out a carriage return and a line feed character. This takes the cursor to the next line automatically.
The scanf function is used to read formatted input data. The format in which input data is to be provided is specified by the scanf function itself as it's first parameter. The scanf function is written as -
scanf(<control string>, &address1, &address2, . . . , &addressn);
Here, the first parameter <control string> contains a list of format specifiers indicating the format and type of data to be read. The remaining parameters - &address1, &address2, ..., &addressn are addresses of the variables where the read data will be stored. scanf reads the input data as per the format specifiers and stores them (i.e., assigns them) to the corresponding addresses. An & is pre-fixed to the variable name to denote its address.
Note that there must be the same number of format specifiers and addresses as there are input data. For instance, in the following example:
scanf("%d %f",&x,&y);
the first argument is a string that contains two format specifiers - %d and %f, the first format specifier (%d) is for argument &x and the second one (%f) is for the argument &y. So, two pieces of input data will be read - the first piece is treated according to %d and the second one is treated according to %f. Format specifiers in the <control string> are always specified for the remaining arguments, in order, from left to right.
Keep in mind that scanf() treats all white-space characters as de-limiters to separate out one data input from the other. So, while entering your data inputs, you can separate them out with a blank space or a tab space character or a newline character.
Each format specifier begins with the percentage character (%) followed by a conversion character which indicates the type of the corresponding data item. Similar control string is also used with the printf function to be discussed later. The meaning of the conversion characters for input/output is given in the table below.
The format specifiers described in the table below apply to both scanf and printf functions.
Format Specifier | Input Data (scanf) | Output Data (printf) |
---|---|---|
%c | reads a single character | single character |
%d | reads a numeric value as signed int. Treats the input data as a decimal number, i.e. a number in the base 10 number system | signed decimal integer |
%i | can read data value provided either as a decimal int, hexadecimal int or octal int | print as a signed decimal integer. |
%o | reads data value as an octal number | prints data as an octal integer without leading zero. |
%x | reads data value as a hexadecimal number | prints data as a hexadecimal integer without leading 0x. |
%u | reads data value as an unsigned integer | prints as an unsigned integer. |
%h | reads data value as a short integer | N/A |
%f | reads data as a floating point value without the exponent (i.e of the form [-]dddd.dddd) | prints as a floating point value (without exponent) |
%e | reads data as a floating point value. The input data can also have an exponent part (eg: -1.2e+5, which means -1.2 x 105) | prints as a floating point value in exponent form |
%E | This is same as %e, except that in this case the exponent is represented with a capital E (eg: -1.2E+5) | |
%g | reads data as a floating point value in either of the format specified for %f or %e | prints as a floating point value. Depending upon the magnitude of the value, it will be displayed either as e-type or f-type conversion. If the value does not have any fractional part, the trailing decimal point is not printed. |
%G | This is same as %g, except that in this case if an exponent is there, it is represented with a capital E. | |
%s | reads data as a string of characters. Reading terminates when a whitespace character is encountered. The read string of characters is appended with a null character '\\0' at the end. | prints a character string. |
%[] | reads data as a string which may even include whitespace characters as well | N/A |
Note: The variable name being a string (an array of characters) is not preceded by &, but the numerical variables rollno and grade are preceded by &. This is because, in case of an array type variable, the variable name itself represents its address in the memory. Also note that while providing data values they must be separated by whitespace character s blank space, tab space, new line character (enter key), etc. which act as de-limiters of individual data items.
Avoid using a new line character (i.e. enter key) to de-limit input values as it can create problems when one or more of the data items is a single character. For instance, in this example, if you typed Sanjay, then pressed enter key, then typed 12345, pressed enter key, and then typed A and pressed enter key, then while name and rollno would get read correctly, grade will take in the \n character (corresponding to the enter key following value 12345) and so A will not get read.
The format specifier can be additionally pre-fixed with a number to indicate the width of the associated data field. See example below:
If the data items provided are 105 40.36 A, then the variables get values x = 105, u = 40.3, c = 6. Note that the character A is ignored. This is because the field width for u is 4 which can accommodate 40.3 (the decimal point is also counted). The next character in the input steam is character 6, which gets assigned to c and A is left un-read.
The printf function is used to output data onto the standard output device. In general, the printf function is written as
printf(<control string>, arg1, arg2, . . . , argn);
where the <control string> refers to a string containing required formatting information as in scanf, and arg1, arg2, ..., argn are individual data variables whose values are to be printed. However, unlike scanf, these data variable names are not preceded by the & symbol. This is because printf is expected to only output the values of these variables and not their addresses.
We will look at a lot of examples so that you develop a clear understanding of the format specifiers. You should also spend some time on the computer, write small codes to try various combinations of the format specifiers and closely observe their effect on the output.
As you notice, the printf statement prints the data values x, y, and c all sticking to each other, followed by a blank line (due to \n at the end of the control string). For clarity of data output, you may separate the format specifiers with blank space or comma (,). So, a better way of writing would be -
printf("%f, %d, %c\n", x, y, c);
orprintf("%f %d %c\n",x,y,z);
We mentioned earlier that you can also pre-fix the format specifier character with a numeric qualifier to indicate the width of field (precision) to be printed. let us look at some example usage of this.
Note that due to the precision specification the floating point variable x has been rounded to fit the specified field width. Also, note that the field width of 2 specified for y is too small as compared to the specified field width supported for integer data items (which is normally 8 digits). When such a precision is specified, it is ignored and the entire integer value is displayed.
Having developed an elementary understanding of the control string in printf, let us now define the format specifier for printf in full. A full format of the format specifier in printf would be like -
%[-][width][flags]format
[ ] implies that the specifiers are optional.
where:
% | : denotes the beginning of a format specifier |
- | : indicates that data is to be displayed as left-justified. If the - is missing, data display is right-justified. |
width | : the width of field or number of spaces to use for displaying |
flags | : precision of output to be displayed |
format | : the format specifier itself |
Leading or trailing blanks may be introduced to fill the minimum field width. The minimum field width is usually 7 character (may vary from one machine to another).
Let us look at an example to illustrate this -
/123.456000/ | when no precision is specified, the default precision is 6 places after decimal |
/ 123.456000/ | 5 blank spaces introduced before the output |
/123.456000 / | 5 blank spaces introduced after the output |
/123.456000/ | the width specifier 2 is ignored |
/123.456/ | decimal places precision specified is 3 |
/123.5/ | note the rounding |
/Hello World!/ | : width specifier ignored |
/ Hello World!/ | : right-justified, pre-filled with 3 blank spaces |
/ Hello/ | : only first 5 characters displayed. 10 blank spaces introduced before |
In the above example if the name is entered with embedded space then the variable stud_name will be assigned all characters until the space, since space will terminate the input stream. So, if input given is - Satyen Bose, stud_name gets Satyen only.
In the above program, the statement A will allow input of any character except the newline character (\n). The ^ symbol before '\n' indicates that '\n' is not allowed - all other characters are allowed. The input stream will be terminated as soon as the user presses the enter key. Most importantly, the user can also input embedded spaces.
The statement B indicates a list of only those characters that are allowed. It will allow input of capital alphabets and spaces only. A preceding ^ in the format specification would have restricted the input to the characters other than specified within the square brackets.
The format specification used with the printf statements that follow will display the following strings on the screen.
(1) A program to convert temperature in Centigrade to Fahrenheit and vice-versa. #include <stdio.h> main() { float c, f, ic, fi; prinitf("\nEnter temperature in Centigrade: "); scanf("%f", &c) ; fflush(stdin); printf("\nThe temperature in Centigrade is: %5.1f\n",c); /* the above statement prints the input in 999.9 format */ f = 1.8 * c + 32; printf("\nThe Fahrenheit equivalent of Centigrade %5.1f is: %5.1f\n", c, f); printf("\nEnter temperature in Fahrenheit: "); scanf("%f", &fi); fflush(stdin); printf("\nThe temperature in Fahreneit is: %5.1f\n",fi); /* the above statements prints the input in 999,9 format */ ic = (fi - 32) / 1.8; printf("\nThe Centigrade equivalent of Fahrenheit %5.1f is: %5.1f\n", fi, ci); } (2) A C program contains the following variable declarations: float a = 14.5, b = 0.00004, c = 9060.; Observe the output produced by each of the below statements. (a) printf("%f %f %f", a, b, c); (b) printf("%2f %2f %2f", a, b, c); (c) printf("%7f %7f %7f", a, b, c); (d) printf("%7.4 %7.4 %7.4", a, b, c); (e) printf("%e %e %e", a, b, c); (f) printf("%4e %4e %4e", a, b, c); (g) printf("%10e %10e %10e", a, b, c); (h) printf("%10.5e % 10.5 % 10.5", a, b, c); (i) printf("% -7f %-7f %-7f", a, b, c); (j) printf("%+7.2f%+7.2f% +7.2f", b, c, b+c); (k) printf("% 07f", a * b); (l) printf("%#6f %#6f", a, b); (m) printf("%g %g", a, b); (n) printf("%#g %#g %#g", a, b/c, c); (3) A C program contains the following variable declarations: char c1 = 'X', c2 = 'Y', c3 = 'Z'; Show the output resulting from each of the following printf statements. (a) printf("%c %c", c1, c2); (b) printf("%4c %4c %c", c1, c2, c3); (c) printf("c1 = %c, c2 = %c, c3 = %c", c1, c2, c3); (4) Consider the following variable declarations and initialization in a C program: char picture[22] = "To kill a mocking bird"; Predict the output of the following printf statements. (a) printf("%s\n", picture); (b) printf("%-30s\n", picture); (c) printf("%30s\n", picture); (d) printf("%.7s\n", picture); (e) printf("%30.7s\n", picture); (f) printf("%-30.7s\n", picture); (5) Write the necessary scanf or printf statement for each of the following situations: (a) Generate the messages. Enter your name: Enter your address: Then enter the name and address. Assign the name and address to character type arrays called name and address respectively. (b) Suppose a and b are integer variables, prompt the user to enter these two variables and then display their sum. Label the output accordingly. (6) Determine as best you can the purpose of each of the following C programs. Identify all variables within each program. Identify all input and output statements, all assignment statements, and any other special features that you recognize. (a) main() { float gross, tax, net; printf("\nEnter Gross Salary: "); scanf("%f",&gross); tax = 0.14 * gross; net = gross - tax; printf("\nTaxes withheld: %.2f\n", tax); printf("\nNet Salary: %.2f\n", net); } (b) main() { int a, b, min; int smaller(a, int b); printf("\nEnter the first number: "); scanf("%d", &a); printf("\nEnter the second number: "); scanf("%d", &b); min = smaller(a,b); printf("\nThe smaller number is: %d", min); } int smaller(int x, int y) { return(x > y)? y:x; } (c) main() { int a,b, min; int larger(int a, int b); printf("\nTo STOP, enter 0 for each number.\n"); printf("\nEnter the first number: "); scanf("%d",&a); printf("\nEnter the second number: "); scanf("%d",&b); while(a != 0 ||b != 0) { max = (a > b)? a:b; printf("\nThe larger number is: %d\n",max); printf("\nEnter the first number: "); scanf("%d",&a); printf("\nEnter the second number: "); scanf("%d",&b); } } (7) Compile and run the following program to understand the format specifications. #include <stdio.h> main() { printf("One %d\n",356); printf("Two %0d\n",356); printf("Three %7d\n",356); printf("Four %-2d\n",681); printf("Five %f\n",3.25968912); printf("Six %e\n",3.25968912); printf("Seven %5.3f\n", 3.25968912); printf("Eight %8.3f\n", 3.25968912); printf("Nine %x\n",17); printf("Ten %0\n",356); }
Elements of the C Language - Identifiers, Keywords, Data types and Data objects
Elements of the C language - Operators and Expressions
Logical constructs in C - if..else & switch..case statements
How to move your Email accounts from one hosting provider to another without losing any mails?
How to resolve the issue of receiving same email message multiple times when using Outlook?
Self Referential Data Structure in C - create a singly linked list
Mosquito Demystified - interesting facts about mosquitoes
Elements of the C Language - Identifiers, Keywords, Data types and Data objects
How to pass Structure as a parameter to a function in C?
Rajeev Kumar is the primary author of How2Lab. He is a B.Tech. from IIT Kanpur with several years of experience in IT education and Software development. He has taught a wide spectrum of people including fresh young talents, students of premier engineering colleges & management institutes, and IT professionals.
Rajeev has founded Computer Solutions & Web Services Worldwide. He has hands-on experience of building variety of websites and business applications, that include - SaaS based erp & e-commerce systems, and cloud deployed operations management software for health-care, manufacturing and other industries.