Creating a Pie Chart Application

Chapter 12 - An Introduction to I/O in C++

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

Streamlining I/O with C++
The software supplied with the Microsoft Visual C++ compiler includes a standard library that contains functions commonly used by the C++ community. The standard I/O library for C, described by the header file STDIO.H, is still available in C++. However, C++ introduces its own header file, called IOSTREAM.H, which implements its own collection of I/O functions.
The C++ stream I/O is described as a set of classes in IOSTREAM.H. These classes overload the “put to” and “get from” operators, << and >>. To better understand why the stream library in C++ is more convenient than its C counterpart, let’s first review how C handles input and output.
First, recall that C has no built-in input or output statements; functions such as printf( ) are part of the standard library but not part of the language itself. Similarly, C++ has no built-in I/O facilities. The absence of built-in I/O gives you greater flexibility to produce the most efficient user interface for the data pattern of the application at hand.
The problem with the C solution to input and output lies with its implementation of these I/O functions. There is little consistency among them in terms of return values and parameter sequences. Because of this, programmers tend to rely on the formatted I/O functions printf( ), scanf( ), and so on—especially when the objects being manipulated are numbers or other noncharacter values. These formatted I/O functions are convenient and, for the most part, share a consistent interface, but they are also big and unwieldy because they must manipulate many kinds of values.
In C++, the class provides modular solutions to your data manipulation needs. The standard C++ library provides three I/O classes as an alternative to C’s general-purpose I/O functions. These classes contain definitions for the same pair of operators—>> and <<—that are optimized for all kinds of data. (See Chapter 16 for a discussion of classes.)
cin, cout, and cerr
The C++ stream counterparts to stdin, stdout, and stderr, prototyped in STDIO.H, are cin, cout, and cerr, which are prototyped in IOSTREAM.H. These three streams are opened automatically when your program begins execution and become the interface between the program and the user. The cin stream is associated with the terminal keyboard. The cout and cerr streams are associated with the video display.
The >> Extraction and << Insertion Operators
Input and output in C++ have been significantly enhanced and streamlined by the stream library operators >> (“get from” or extraction) and << (“put to” or insertion). One of the major enhancements that C++ added to C was operator overloading. Operator overloading allows the compiler to determine which like-named function or operator is to be executed based on the associated variables’ data types. The extraction and insertion operators are good examples of this new C++ capability. Each operator has been overloaded so it can handle all of the standard C++ data types, including classes. The following two code segments illustrate the greater ease of use for basic I/O operations in C++. First, take a quick look at a C output statement using printf( ):
printf(“Integer value: %d, Float value: %f”,ivalue,fvalue);
Here is the C++ equivalent:
cout << “Integer value: ” << ivalue << “, Float value: ”
    << fvalue;
A careful examination of the C++ equivalent will reveal how the insertion operator has been overloaded to handle the three separate data types: string, integer, and float. If you are like many C programmers, you are not going to miss having to hunt down the % symbol needed for your printf( ) and scanf( ) format specifications. As a result of operator overloading, the insertion operator will examine the data type you have passed to it and determine an appropriate format.
An identical situation exists with the extraction operator, which performs data input. Look at the following C example and its equivalent C++ counterpart:
/* C code */
scanf(“%d%f%c”,&ivalue,&fvalue,&c);

// C++ code
cin >> ivalue >> fvalue >> c;
No longer is it necessary to precede your input variables with the & address operator. In C++, the extraction operator takes care of calculating the storage variable’s address, storage requirements, and formatting.
Having looked at two examples of the C++ operators << and >>, you might be slightly confused as to why they are named the way they are. The simplest way to remember which operator performs output and which performs input is to think of these two operators as they relate to the stream I/O files. When you want to input information, you extract it (>>) from the input stream, cin, and put the information into a variable—for example, ivalue. To output information, you take a copy of the information from the variable fvalue and insert it (<<) into the output stream, cout.
As a direct result of operator overloading, C++ will allow a program to expand upon the insertion and extraction operators. The following code segment illustrates how the insertion operator can be overloaded to print the new type stclient:
ostream& operator << (ostream& osout, stclient staclient)
{
 osout << “ ” << staclient.pszname;
 osout << “ ” << staclient.pszaddress;
 osout << “ ” << staclient.pszphone;
}
Assuming the structure variable staclient has been initialized, printing the information becomes a simple one-line statement:
cout << staclient;
Last but not least, the insertion and extraction operators have an additional advantage—their final code size. The general-purpose I/O functions printf( ) and scanf( ) carry along code segments into the final executable version of a program that are often unused. In C, even if you are dealing only with integer data, you still pull along all of the conversion code for the additional standard data types. In contrast, the C++ compiler incorporates only those routines actually needed.
The following program demonstrates how to use the input, or extraction, operator >> to read different types of data:
//
//  insrt1.cpp
//  A C++ program demonstrating how to use the
//  extraction >> operator to input a char,
//  integer, float, double, and string.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

#define INUMCHARS 45
#define INULL_CHAR 1

void main(void)
{
 char canswer;
 int ivalue;
 float fvalue;
 double dvalue;
 char pszname[INUMCHARS + INULL_CHAR];
 cout << “This program allows you to enter various data types.”;
 cout << “Would you like to try it? ”<< “\n\n”;
 cout << “Please type a Y for yes and an N for no: ”;

 cin  >> canswer;

 if(canswer == ‘Y’) {

   cout << “\n” << “Enter an integer value: ”;
   cin >> ivalue;
   cout << “\n\n”;

   cout << “Enter a float value: ”;
   cin >> fvalue;
   cout << “\n\n”;

   cout << “Enter a double value: ”;
   cin >> dvalue;
   cout << “\n\n”;

   cout << “Enter your first name: ”;
   cin >> pszname;
   cout << “\n\n”;
 }

}
In this example, the insertion operator << is used in its simplest form to output literal string prompts. Notice that the program uses four different data types and yet each input statement, cin >>, looks identical except for the variable’s name. For those of you who are fast typists but are tired of trying to find the infrequently used %, “, and & symbols (required by scanf( )), you can give your fingers and eyes a rest. The C++ extraction operator makes code entry much simpler and less error prone.
Because of the rapid evolutionary development of C++, you have to be careful when using C or C++ code found in older manuscripts. For example, if you had run the previous program under a C++ compiler, Release 1.2, the program execution would look like the following example:
This program allows you to enter various data types
Would you like to try it?

Please type a Y for yes and an N for no: Y

Enter an integer value:
                       10
This is because the C++ Release 1.2 input stream is processing the newline character you entered after typing the letter “Y.” The extraction operator >> reads up to, but does not get rid of, the newline. The following program solves this problem by adding an additional input statement:
//
//  insrt2.cpp
//  A C++ program demonstrating how to use the
//  extraction >> operator to input a char,
//  integer, float, double, and string.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

#define INUMCHARS 45
#define INULL_CHAR 1

void main(void)
{
 char canswer,cAnewline;
 int ivalue;
 float fvalue;
 double dvalue;
 char pszname[INUMCHARS + INULL_CHAR];

 cout << “This program allows you to enter various data types.”;
 cout << “Would you like to try it?” << “\n\n”;
 cout << “Please type a Y for yes and an N for no: ”;

 cin  >> canswer;
 cin.get(cAnewline);

 if(canswer == ‘Y’) {

   cout << “\n” << “Enter an integer value: ”;
   cin >> ivalue;
   cout << “\n\n”;

   cout << “Enter a float value: ”;
   cin >> fvalue;
   cout << “\n\n”;

   cout << “Enter a double value: ”;
   cin >> dvalue;
   cout << “\n\n”;

   cout << “Enter your first name: ”;
   cin >> pszname;
   cout << “\n\n”;
 }

}
Did you notice the change?  After canswer is read in, the program executes
cin.get(cAnewline);
This processes the newline character so that when the program runs, it then looks like this:
This program allows you to enter various data types
Would you like to try it?

Please type a Y for yes and an N for no:

Enter an integer value: 10
Both algorithms work properly since the introduction of C++ Release 2.0. However, it is worth mentioning that you must take care when modeling your code from older texts. Mixing what is known as historic C and C++ with current compilers can cause you to spend many hours trying to figure out why your I/O doesn’t perform as expected.
This next example demonstrates how to use the output, or insertion, operator << in its various forms:
//
//  extrct.cpp
//  A C++ program demonstrating how to use the
//  insertion << operator to input a char,
//  integer, float, double, and string.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

void main(void)
{
 char c=’A’;
 int ivalue=10;
 float fvalue=45.67;
 double dvalue=2.3e32;
 char fact[]="For all have...";

 cout << “Once upon a time there were ”;
 cout << ivalue << “ people.”<< endl;
 cout << “Some of them earned ” << fvalue;
 cout << “ dollars per hour.” << “\n”;
 cout << “While others earned ” << dvalue << “ per year!”;
 cout << “\n\n” << “But you know what they say: ”;
 cout << fact << “\n\n”;
 cout << “So, none of them get an ”;
 cout << c;
 cout << “!”;

}
The output from the program looks like this:
Once upon a time there were 10 people.
Some of them earned 45.67 dollars per hour.
While others earned 2.3e+32 per year!

But you know what they say: “For all have...”

So, none of them get an A!
When comparing the C++ source code with the output from the program, one thing you should immediately notice is that the insertion operator << does not automatically generate a newline. You still have complete control over when this occurs by including the newline symbol \n or endl when necessary.
endl is very useful for outputting data in an interactive program because it not only inserts a newline into the stream but also flushes the output buffer. You can also use flush; however, this does not insert a newline. Notice too that the placement of the newline symbol can be included after its own << insertion operator or as part of a literal string, as is contrasted in the second and fourth << statements in the program.
Also notice that while the insertion operator very nicely handles the formatting of integers and floats, it isn’t very helpful with doubles. Another interesting facet of the insertion operator has to do with C++ Release 1.2 character information. Look at the following line of code:
cout << c;
This would have given you the following output in Release 1.2:
So, none of them get an 65!
This is because the character is translated into its ASCII equivalent. The Release 1.2 solution is to use the put( ) function for outputting character data. This would require you to rewrite the statement in the following form:
cout.put(c);
Try running this next example:
//
//  string.cpp
//  A C++ program demonstrating what happens when you use
//  the extraction operator >> with string data.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

#define INUMCHARS 45
#define INULL_CHARACTER 1

void main(void)
{
 char pszname[INUMCHARS + INULL_CHARACTER];

 cout << “Please enter your first and last name: ”;
 cin >> pszname;
 cout << “\n\nThank you, ” << pszname;

}
A sample execution of the program looks like this:
Please enter your first and last name: Kirsten Tuttle

Thank you, Kirsten
There is one more fact you need to know when inputting string information. The extraction operator >> is written to stop reading in information as soon as it encounters white space. White space can be a blank, tab, or newline. Therefore, when pszname is printed, only the first name entered is output. You can solve this problem by rewriting the program and using the cin.get( ) function:
//
//  cinget.cpp
//  A C++ program demonstrating what happens when you use
//  the extraction operator >> with cin.get( ) to process an
//  entire string.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

#define INUMCHARS 45
#define INULL_CHARACTER 1

void main(void)
{
 char pszname[INUMCHARS + INULL_CHARACTER];

 cout << “Please enter your first and last name: ”;
 cin.get(pszname,INUMCHARS);
 cout << “\n\nThank you, ” << pszname;
}
The output from the program now looks like this:
Please enter your first and last name: Kirsten Tuttle

Thank you, Kirsten Tuttle
The cin.get( ) function has two additional parameters. Only one of these, the number of characters to input, was used in the previous example. The function cin.get( ) will read everything, including white space, until the maximum number of characters specified has been read in or up to the next newline, whichever comes first. The optional third parameter, not shown, identifies a terminating symbol. For example, the following line would read into pszname INUMCHARS characters all of the characters up to but not including a * symbol, or a newline, whichever comes first:
cin.get(pszname,INUMCHARS,’*’);

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net