First of all we need to learn about streams in C Programming. All C Programming input and output is done with streams, no matter where input is coming from or where output is going to. This is the standard way of handling all input and output and has definite advantages for the programmer. A library package has been evolved which is known as known as the ?Standard I/O Library? which is used in any C program by using stdio.h header. Of course, now that we know its importance, it is essential that we understand what streams are and how they work. First, however, we need to understand exactly what the terms input and output mean in context of C.
The C programming language provides input and output support using library functions, which gives an advantage to system designers to tailor their input and output on their own.
What Exactly Is Program Input/Output?
A C program keeps data in random access memory (RAM) while executing. This data is in the form of variables, structures, and arrays that have been declared by the program. The question is where did this data come from, and what can the program do with it?
- Data can come from some location external to the program. Data moved from an external location into RAM, where the program can access it, is called input. The keyboard and disk files are the most common sources of program input.
- Data can also be sent to a location external to the program; this is called output. The most common destinations for output are the screen, a printer, and disk files.
Input sources and output destinations are collectively referred to as devices. The keyboard is a device; the screen is a device, and so on. Some devices (the keyboard) are for input only, others (the screen) are for output only, and still others (disk files) are for both input and output. Whatever the device, and whether it’s performing input or output, C carries out all input and output operations by means of streams.
What is a Stream?
A stream is a sequence of characters. More exactly, it is a sequence of bytes of data. A sequence of bytes flowing into a program is an input stream; a sequence of bytes flowing out of a program is an output stream. By focusing on streams, we don’t have to worry as much about where they’re going or where they originated.
The major advantage of streams, therefore, is that input/output programming is device independent. Programmers don’t need to write special input/output functions for each device (keyboard, disk, and so on). The program sees input/output as a continuous stream of bytes no matter where the input is coming from or going to.
Every C stream is connected to a file. In this context, the term file doesn’t refer to a disk file. Rather, it is an intermediate step between the stream that the program deals with and the actual physical device being used for input or output. For the most part, the beginning C programmer doesn’t need to be concerned with these files, because the details of interactions between streams, files, and devices are taken care of automatically by the C library functions and the operating system.
Modes of Streams in C Language
C streams can be divided into two modes: text and binary.
Text Stream
A text stream consists only of characters, such as text data being sent to the screen. Text streams are organized into lines, which can be up to 255 characters long and are terminated by an end-of-line, or newline, character. Certain characters in a text stream are recognized as having special meaning, such as the newline character.
Binary Stream
A binary stream can handle any sort of data, including, but not limited to, text data. Bytes of data in a binary stream aren’t translated or interpreted in any special way; they are read and written exactly as-is. Binary streams are used primarily with disk files.
Predefined Streams
ANSI C has three predefined streams, also referred to as the standard input/output files. If you’re programming for an IBM-compatible PC running DOS, two additional standard streams are available to you. These streams are automatically opened when a C program starts executing and are closed when the program terminates. The programmer doesn’t need to take any special action to make these streams available. Table lists the standard streams and the devices they normally are connected with. All five of the standard streams are text-mode streams.
Whenever we have to use the printf() or puts() functions to display text on-screen, we use the stdout stream. Likewise, when we use gets() or scanf() to read keyboard input, we use the stdin stream. The standard streams are opened automatically, but other streams, such as those used to manipulate information stored on disk, must be opened explicitly.
Stream functions in C Language
The C standard library has a variety of functions that deal with stream input and output. Most of these functions come in two varieties: one that always uses one of the standard streams, and one that requires the programmer to specify the stream.
These functions are listed in table below. This table doesn’t list all of C’s input/output functions.
All these functions require that we include STDLIB.H. The function perror() may also require STDLIB.H. The functions vprintf() and vfprintf() also require STDARGS.H. On UNIX systems, vprintf() and vfprintf() may also require VARARGS.H. The compiler’’s Library Reference will state whether any additional or alternative header files are needed.
Accepting Keyboard Input
Most C programs require some form of input from the keyboard (that is, from stdin). Input functions are divided into a hierarchy of three levels: character input, line input, and formatted input.
Character Input
The character input functions read input from a stream one character at a time. When called, each of these functions returns the next character in the stream, or EOF if the end of the file has been reached or an error has occurred. EOF is a symbolic constant defined in STDIO.H as -1. Character input functions differ in terms of buffering and echoing.
- Some character input functions are buffered. This means that the operating system holds all characters in a temporary storage space until you press Enter, and then the system sends the characters to the stdin stream. Others are unbuffered, meaning that each character is sent to stdin as soon as the key is pressed.
- Some input functions automatically echo each character to stdout as it is received. Others don”t echo; the character is sent to stdin and not stdout. Because stdout is assigned to the screen, that’’s where input is echoed.
The uses of buffered, unbuffered, echoing, and nonechoing character input are explained in the following sections.
The getchar() function
The function getchar() obtains the next character from the stream stdin. It provides buffered character input with echo, and its prototype is
int getchar(void);
The use of getchar() is demonstrated below. Notice that the putchar() function, explained in detail, simply displays a single character on-screen.
The getchar() function.
On line 9, the getchar() function is called and waits to receive a character from stdin. Because getchar() is a buffered input function, no characters are received until we press Enter. However, each key we press is echoed (showed) immediately on the screen.
When we press Enter, all the characters we entered, including the newline, are sent to stdin by the operating system. The getchar() function returns the characters one at a time, assigning each in turn to ch.
Each character is compared to the newline character \n and, if not equal, displayed on-screen with putchar(). When a newline is returned by getchar(), the while loop terminates.
The getchar() function can be used to input entire lines of text, as shown below. However, other input functions are better suited for this task
Using the getchar() function to input an entire line of text
This program is similar to the previous function in the way that it uses getchar(). An extra condition has been added to the loop. This time the while loop accepts characters from getchar() until either a newline character is reached or 80 characters are read. Each character is assigned to an array called buffer. When the characters have been input, line 15 puts a null on the end of the array so that the printf() function on line 17 can print the entered string.
On line 9, why was buffer declared with a size of MAX + 1 instead of just MAX? If we declare buffer with a size of MAX + 1, the string can be 80 characters plus a null terminator. So don”t forget to include a place for the null terminator at the end of the strings.
The getch() function
The getch() function obtains the next character from the stream stdin. It provides unbuffered character input without echo. The getch() function isn”t part of the ANSI standard. This means that it might not be available on every system. Additionally, it might require that different header files be included. Generally, the prototype for getch() is in the header file CONIO.H, as follows:
int getch(void);
Because it is unbuffered, getch() returns each character as soon as the key is pressed, without waiting for the user to press Enter. Because getch() doesn’t echo its input, the characters aren”t displayed on-screen. Listing 14.4 illustrates the use of getch().
The following function uses getch(), which is not ANSI-compliant. There is no guarantee that all compilers support non-ANSI functions.
Testing the getch() function.
Note : This program will run on turbo c & c++ compiler not on gnu compiler.
When this program runs, getch() returns each character as soon as we press a key–it doesn”t wait for us to press Enter. There’s no echo, so the only reason that each character is displayed on-screen is the call to putchar(). To get a better understanding, add a semicolon to the end of line 10 and remove line 11 (putchar(ch)). When we rerun the program, you will find that nothing
we type is echoed to the screen. The getch() function gets the characters without echoing them to the screen. We know the characters are being gotten because the original listing used putchar() to display them.
we type is echoed to the screen. The getch() function gets the characters without echoing them to the screen. We know the characters are being gotten because the original listing used putchar() to display them.
Why does this program compare each character to \r instead of to \n? The code \r is the escape sequence for the carriage return character. When we press Enter, the keyboard device sends a carriage return to stdin. The buffered character input functions automatically translate the carriage return to a newline, so the program must test for \n to determine whether Enter has been pressed. The
unbuffered character input functions don”t translate, so a carriage return is input as \r, and that’’s what the program must test for.
unbuffered character input functions don”t translate, so a carriage return is input as \r, and that’’s what the program must test for.
The next function uses getch( ) to input an entire line of text. Running this program clearly illustrates that getch( ) doesn”t echo its input.
Using the getch() function to input an entire line.
Remember that getch() isn’t an ANSI-standard command. This means that your compiler (and other compilers) might or might not support it. getch() is supported by Symantec and Borland.
Note : The getch() is a function of conio.h library so this program will run on turbo c & turbo c++ compiler not on gnu compiler because conio.h is unidentified for gnu compiler in case of c program.
The getche() function
getche() is exactly like getch(), except that it echoes each character to stdout. Modify the first program in the getch() portion to use getche() instead of getch() and when the program runs, each key we press is displayed on-screen twice–once as echoed by getche(), and once as echoed by putchar(). getche() is not an ANSI-standard command, but many C compilers support it.
The getc() & fgetc() function
The getc() & fgetc() function
The getc() and fgetc() character input functions don”t automatically work with stdin. Instead, they let the program specify the input stream. They are used primarily to read characters from disk files.These will discuss in file managment.
Ungetting the character with ungetc()
Ungetting the character with ungetc()
Suppose that the program is reading characters from an input stream and can detect the end of input only by reading one character too many. For example, we might be inputting digits only, so we know that input has ended when the first nondigit character is encountered. That first nondigit character might be an important part of subsequent data, but it has been removed from the input
stream. Is it lost? No, it can be “ungotten” or returned to the input stream, where it is then the first character read by the next input operation on that stream.
stream. Is it lost? No, it can be “ungotten” or returned to the input stream, where it is then the first character read by the next input operation on that stream.
To “unget” a character, we use the ungetc() library function. Its prototype is
int ungetc(int ch, FILE *fp);
The argument ch is the character to be returned. The argument *fp specifies the stream that the character is to be returned to, which can be any input stream. For now, simply specify stdin as the second argument: ungetc(ch, stdin);. The notation FILE *fp is used with streams associated with disk files.
We can unget only a single character to a stream between reads, and can”t unget EOF at any time. The function ungetc() returns ch on success and EOF if the character can”t be returned to the stream.
Line/String Input
The line input functions read a line from an input stream. They read all characters up to the next newline character ‘\n’. The standard library has two line input functions, gets() and fgets().
The gets() function
The gets() function
This is a straight forward function, reading a line from stdin and storing it in a string. The function prototype is
char *gets(char *str);
gets() takes a pointer to type char as its argument and returns a pointer to type char. The gets() function reads characters from stdin until a newline (\n) or end-of-file is encountered; the newline is replaced with a null character, and the string is stored at the location indicated by str.
The return value is a pointer to the string (the same as str). If gets() encounters an error or reads end-of-file before any characters are input, a null pointer is returned.
Before calling gets(), we must allocate sufficient memory space to store the string. This function has no way of knowing whether space pointed to by ptr is allocated; the string is input and stored starting at ptr in either case. If the space hasn’t been allocated, the string might overwrite other data and cause program errors.
Using gets() to input string from keyboard
In this example, the argument to gets() is the expression input, which is the name of a type char array and therefore a pointer to the first array element. The array is declared with 81 elements in line 7. Because the maximum line length possible on most computer screens is 80 characters, this array size provides space for the longest possible input line (plus the null character that gets()
adds at the end).
adds at the end).
Output :
Enter some text, then press Enter: This is a test You entered: This is a test
The gets() function has a return value. gets() returns a pointer to type char with the address where the input string is stored. This is the same value that is passed to gets(), but having the value returned to the program in this way lets your program test for a blank line.
If we enter a blank line (that is, if we simply press Enter) in response to line 18, the string (which contains 0 characters) is still stored with a null character at the end. Because the string has a length of 0, the null character is stored in the first position. This is the position pointed to by the return value of gets(), so if we test that position and find a null character, we know that a blank line was entered.
The fgets() function
Line 15 contains the fgets() function. When running the program, enter lines of length less than and greater than MAXLEN to see what happens. If a line greater than MAXLEN is entered, the first MAXLEN – 1 characters are read by the first call to fgets(); the remaining characters remain in the keyboard buffer and are read by the next call to fgets() or any other function that reads from stdin. The program exits when a blank line is entered (lines 17 and 18).
Using the gets() return value to test for the input of a blank line
Note : This source code is valid for turbo c and c++ not for gnu compiler.If we enter a blank line (that is, if we simply press Enter) in response to line 18, the string (which contains 0 characters) is still stored with a null character at the end. Because the string has a length of 0, the null character is stored in the first position. This is the position pointed to by the return value of gets(), so if we test that position and find a null character, we know that a blank line was entered.
The fgets() function
The fgets() library function is similar to gets() in that it reads a line of text from an input stream. It’s more flexible, because it lets the programmer specify the specific input stream to use and the maximum number of characters to be input. The fgets() function is often used to input text from disk files. To use it for input from stdin, we specify stdin as the input stream. The prototype of fgets() is
char *fgets(char *str, int n, FILE *fp);
The last parameter, FILE *fp, is used to specify the input stream. Simply specify the standard input stream, stdin, as the stream argument.
The pointer str indicates where the input string is stored. The argument n specifies the maximum number of characters to be input. The fgets() function reads characters from the input stream until a newline or end-of-line is encountered or n – 1 characters have been read. The newline is included in the string and terminated with a \0 before it is stored. The return values of fgets() are the
same as described earlier for gets().
same as described earlier for gets().
Strictly speaking, fgets() doesn’t input a single line of text (if you define a line as a sequence of characters ending with a newline). It can read less than a full line if the line contains more than n -1 characters. When used with stdin, execution doesn’t return from fgets() until you press Enter, but only the first n-1 characters are stored in the string. The newline is included in the string only if it falls within the first n-1 characters.
Formatted Input
The input functions covered up to this point have simply taken one or more characters from an input stream and put them somewhere in memory. No interpretation or formatting of the input has been done, and you still have no way to input numeric variables. For example, how would you input the value 12.86 from the keyboard and assign it to a type float variable? Enter the scanf() and fscanf() functions.These two functions are identical, except that scanf() always uses stdin, whereas the user can specify the input stream in fscanf(). This section covers scanf(); fscanf() generally is used with disk file input.
The scanf() function
Syntax:
scanf (format-control-string,o th er -a rg umen ts)
The scanf() function takes a variable number of arguments; it requires a minimum of two. The first argument is a format string that uses special characters to tell scanf() how to interpret the input. The second and additional arguments are the addresses of the variable(s) to which the input data is assigned. Here’s an example:
scanf("%d", &x);
The first argument, “%d”, is the format string. In this case, %d tells scanf() to look for one signed integer value. The second argument uses the address-of operator (&) to tell scanf() to assign the input value to the variable x.The scanf() format string can contain the following:
- Spaces and tabs, which are ignored (they can be used to make the format string more readable).
- Characters (but not %), which are matched against non-white-space characters in the input.
- One or more conversion specifications, which consist of the % character followed by special characters. Generally, the format string contains one conversion specification for each variable.
- The optional assignment suppression flag (*) immediately follows the %. If present, this character tells scanf() to perform the conversion corresponding to the current conversion specifier but to ignore the result (not assign it to any variable).
- The next component, the field width, is also optional. The field width is a decimal number specifying the width, in characters, of the input field. In other words, the field width specifies how many characters from stdin scanf() should examine for the current conversion. If a field width isn’t specified, the input field extends to the next white space.
- The next component is the optional precision modifier, a single character that can be h, l, or L. If present, the precision modifier changes the meaning of the type specifier that follows it.
- The only required component of the conversion specifier (besides the %) is the type specifier. The type specifier is one or more characters that tell scanf() how to interpret the input. These characters are listed and described in the table given below. The Argument column lists the required type of the corresponding variable.
Before seeing some examples of scanf(), we need to understand the precision modifiers.
Handling Extra Characters
Input from scanf() is buffered; no characters are actually received from stdin until the user presses Enter. The entire line of characters then “arrives” from stdin, and is processed, in order, by scanf(). Execution returns from scanf() only when enough input has been received to match the specifications in the format string. Also, scanf() processes only enough characters from stdin tosatisfy its format string. Extra, unneeded characters, if any, remain waiting in stdin. These characters can cause problems.
When a call to scanf() is executed and the user has entered a single line, we can have three situations. For these examples, assume that scanf(“%d %d”, &x, &y); is being executed; in other words, scanf() is expecting two decimal integers. Here are the possibilities:
- The line the user inputs matches the format string. For example, suppose the user enters 12 14 followed by Enter. In this case, there are no problems.
- scanf() is satisfied, and no characters are left over in stdin. The line that the user inputs has too few elements to match the format string. For example, suppose the user enters 12 followed by Enter. In this case, scanf() continues to wait for the missing input. Once the input is received, execution continues, and no characters are left over in stdin.
- The line that the user enters has more elements than required by the format string. For example, suppose the user enters 12 14 16 followed by Enter. In this case, scanf() reads the 12 and the 14 and then returns. The extra characters, the 1 and the 6, are left waiting in stdin.
puts("Enter your age."); scanf("%d", &age); puts("Enter your first name."); scanf("%s", name);
Say, for example, that in response to the first prompt, the user decides to be precise and enters 21.00 and then presses Enter. The first call to scanf() is looking for an integer, so it reads the characters 21 from stdin and assigns the value 21 to the variable age.
The characters .00 are left waiting in stdin. The next call to scanf() is looking for a string. It goes to stdin for input and finds .00 waiting there. The result is that the string .00 is assigned to name.
A solution is to make sure there are no extra characters waiting in
stdin before prompting the user for input. We can do this by calling
gets(), which reads any remaining characters from stdin,up to and including the end of the line. Rather than calling gets() directly from the program, we can put it in a separate function with the descriptive name of clear_kb().