You are on page 1of 15

Basic Input and Output

Most useful programs require some data to be provided to them for processing
(input), and will produce a further set of data as a result of that processing
(output). C carries out input and output operations via streams that allow it to
communicate with input and output devices. The term stream refers to the
sequential flow of data to an output device or from an input device.

There are two types of stream - text and binary. For the moment, we are chiefly
concerned with text streams. Text streams are composed of lines of text, each
with zero or more characters, terminated by a newline character. Text streams
may only contain printable characters, the tab character, and the newline
character. When a program runs there are three streams available - standard
input (stdin), standard output (stdout), and standard error (stderr - we will look at
this stream elsewhere). The standard input device is usually the keyboard, while
the standard output device is usually the screen.

We have already used the printf() function several times to print information to
the screen. We will shortly be looking at using the scanf() function to get input
from the keyboard. The printf() and scanf() functions are part of a library of input
and output functions known as the standard input/output library. Any program
that uses any of these functions must use the #include preprocessor directive to
include this library file as follows:

# include <stdio.h>

The most basic form of input and output operation is to read a single character
from the keyboard and display it on the screen. The following short program
demonstrates the use of the getchar() function, which as its name suggests
reads a character from the standard input device:

// example program 1

# include <stdio.h>
void main()
{
char str[1];
char c;

printf("Enter a single character: ");


c = getchar(); // get a character from the keyboard
printf("\n\nThe character you entered is: %c", c);
fflush(stdin); // clear the input buffer
printf("\n\nPress ENTER to continue . . . ");
gets(str);
}

The output from example program 1


The complementary function to getchar() is putchar(), which as its name
suggests writes a single character to the standard output device. The following
short program demonstrates the use of the putchar() function:

// Example program 2

# include <stdio.h>

void main()
{
char str[1];
char c;

printf("Enter a single character: ");


c = getchar(); // get a character from the keyboard
printf("\n\nThe character you entered is: ");
putchar(c); // output the character
fflush(stdin); // clear the input buffer
printf("\n\nPress ENTER to continue . . . ");
gets(str);
}
The output from example program 2

Note that the program does exactly the same thing as the previous example. It
simply does it in a different way (i.e. by using the putchar() function to output the
character).

When dealing with text input, it is more often the case that the user will be typing
in several characters at a time. In other words, they will be entering a string of
characters rather than just a single character. The gets() function accepts a
string of characters from the standard input device, while its equivalent output
function, puts(), outputs a string to the standard output device.

There is no specific string type in C, although there is in many other


programming languages. A string in C is in fact an array of type char.
Both gets() and puts() accept a single argument, which is the name of
an array of type char.

The gets() function accepts characters from the standard input device (normally
the keyboard) and stores them in the character array referenced by the variable
name passed to it as a parameter. As soon as the ENTER key is pressed, the
function appends a null character to the array to terminate (mark the end of) the
string, and control is returned to the line of code after the one that called
the gets() function.

The character array must be large enough to hold the input string - any
characters typed in by the user beyond the number of characters specified for the
string (minus one for the null terminating character) will simply be lost.

The short program below demonstrates the use of


the gets() and puts() functions (note that we have already used
the gets() function several times to capture the user pressing the ENTER key to
end a program).

// Example program 3

# include <stdio.h>

void main()
{
char str[101];

printf("Enter a word or phrase up to 100


characters:\n\n");
gets(str); // get the string from the keyboard
printf("\n\nThe string you entered is:\n\n");
puts(str); // output the string to the screen
fflush(stdin); // clear the input buffer
printf("\n\nPress ENTER to continue . . . ");
gets(str);
}
The output from example program 3

The gets() function is OK for inputting strings of a known maximum length, but its
use is generally discouraged because its use can lead to buffer overflows, and as
such represents a potential security problem (I won't go into details here). A
function that gives us more control over the format of the input data, and which is
also declared in the stdio.h header file, is scanf(). The scanf() function has a
similar syntax to the printf() function that we have already used, and has the
general format:

scanf(char *format, argument, argument, ...);

The format string consists of one or more conversion specifiers that determine
what type of data is to be read from the keyboard, and is followed by a comma-
separated list of arguments, each of which is the address of a variable. The
following short program illustrates how scanf() could be used:

// Example program 4

# include <stdio.h>
# include <conio.h>

void main()
{
int i;
float x;

printf("What are your favorite numbers?\n\n");


printf("(Enter an integer and a float.)\n\n");
scanf("%d%f", &i, &x);
printf("\nYour favorite numbers are %d and %f!\n", i, x);
printf("\n\nPress any key to continue.");
getch();
}
The output from example program 4

The format string "%d%f" specifies that we expect an integer and a float to be
entered. The input values will be stored at &i and &x respectively. The type for
each argument must correspond to the elements specified in the format string.
We have seen the same kind of thing used with the printf() function to specify
the type of each variable (e.g. integer, float, string etc.) passed to the function as
an argument.

The conversion specifier consists of the percent sign (%) followed by a type
specifier that indicates the data type (e.g. f for float). There may optionally be an
additional character (or flag) between the percent sign and the type specifier, as
well as a number for specifying field width or precision. Some of the commonly
used format identifiers are listed in the table below.
Common Format Specifiers

Specifier Meaning

%c character

%d decimal signed integer

%f floating point number

%i decimal signed integer

%ld long decimal integer

%o octal integer

%s string

%u unsigned decimal integer

%x hexadecimal integer (using lower case a-f)

%X hexadecimal integer (using upper case A-F)

A single format specifier can have up to six components, as shown in the table
below. If used, they must appear in the order shown.
Format Specifier Components

% flags min field width period precision, max field width Type specifier

required optional optional optional optional required

One or more flags can be used immediately following the % symbol. Their
purpose is to modify the default behaviour of the format identifiers that follow. For
example, a minus sign causes the item to be displayed left-justified, while a zero
causes the field to be padded with zeros rather than blanks. The exact meaning
of minimum field width, maximum field width and precision depend on the data
type being represented, as demonstrated by the two examples below.

1. %8.2f - this specifies a floating point value, with a total field width of
eight characters, and with the last two characters displaying the decimal
part of the number.
2. %4.8s - this specifies a string value, with a minimum width of four
characters, and a maximum width of eight characters (if the string
exceeds eight characters, it will be truncated).

As well as format specifiers like those described above, the conversion string
passed to the printf() function may contain string literals and escape characters.
The number and type of arguments passed to both printf() and scanf() can vary,
but must be matched by the number of format specifiers in the conversion string.
The somewhat longer program below reads integer values from the keyboard,
calculates the average of the values entered, and displays the smallest value
entered, the largest value entered, the sum of the values entered, and the
average value as calculated.

// Example program 5
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

void main()
{
float temp = 0.0, total = 0.0, average = 0.0;
int sample = 255, sample_no = 0;
int min = 255, min_sample_no = 0;
int max = 0, max_sample_no = 0;

while(sample != 0)
{
printf("\n\nEnter a number between 1 and 254");
printf(" (or 0 to terminate data entry): ");
scanf("%f", &temp );
sample = (int) temp;
if ((sample > 0) && (sample < 255))
{
sample_no += 1;
total += sample;
if((sample < min) && (sample > 0))
{
min = sample;
min_sample_no = sample_no;
}

if((sample > max) && (sample < 255))


{
max = sample;
max_sample_no = sample_no;
}
}
else if(sample != 0)
{
printf("\nYou entered an invalid value. ");
printf("Press any key to continue . . . ");
getch();
}
}
if(total == 0.0)
{
printf("\n\nYou did not enter any values!\n\n");
printf("Press any key to continue . . . ");
getch();
exit(0);
}
average = total / sample_no;
printf("\n\nNumber of entries read: %i\n\n", sample_no);
printf("Sum of values entered: %0.0f\n\n", total);
printf("Largest number entered: %i (sample number
%i)\n\n", max, max_sample_no);
printf("Smallest number entered: %i (sample number
%i)\n\n", min, min_sample_no);
printf("Average value: %6.2f\n\n", average);
printf("Press any key to continue . . . ");
getch();
}
The output from example program 5

The sscanf() function is closely related to the scanf() function, and is also
declared in stdio.h. It allows you to get data from a buffer (a string variable, for
example). The general format for sscanf() is:

char sscanf(const char *buff, const char *format, ...);

The first argument is the address of the buffer from which the sscanf() function
obtains its input. This is followed by a format string that determines what type of
data is to be read from the buffer, then the addresses of the variables (separated
by commas) to which the values read are to be assigned. The following example
illustrates how sscanf() can be used to extract substrings from a string.
// Example program 6

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

void main()
{
char input_string[30] = " 47.0000 10:00:56 ";
char temperature_string[8];
char time_string[9];
int temperature;

sscanf(input_string, "%7s %8s", temperature_string,


time_string);
temperature = atoi(temperature_string);
printf("\nTemperature is: %8.4f\n", (float) temperature);
printf("\nThe time recorded was: %s\n", time_string);
printf("\n\nPress any key to exit . . . ");
getch();
}
The output from example program 6

You might also like