16.10 C-Style Conversion Routines

I l @ ve RuBoard

C++ uses the << operator for formatted output and the >> operator for formatted input. C has its own set of output functions (the pstd::printf family) and input conversion functions (the std::scanf functions). This section goes into the details of these C-style conversion routines.

16.10.1 The std::printf Family of Output Functions

C uses the std::printf function call and related functions for output. A std::printf call consists of two parts : a format that describes how to print the data and a list of data to print.

The general form of the std::printf call is:

 std::printf(   format   , p   arameter-1, parameter-   2, ...); 

The format string is printed exactly. For example:

 std::printf("Hello World\n"); 

prints:

 Hello World 

To print a number, you must put a % conversion in the format string. For example, when C sees %d in the format string, it takes the next parameter from the parameter list (which must be an integer) and prints it.

Figure 16-1 shows how the elements of the std::printf statement work to generate the final result.

Figure 16-1. std::printf structure
figs/c++2_1601.gif

The conversion %d is used for integers. Other types of parameters use different conversions. For example, if you want to print a floating-point number, you need a %f conversion. Table 16-9 lists the conversions.

Table 16-9. C-style conversions

Conversion

Variable type

%d

int

%ld

long int

%d

short int

%f

float

%lf

double

%u

unsigned int

%lu

unsigned long int

%u

unsigned short int

%s

char * (C-style string)

%c

char

%o

int (prints octal)

%x

int (prints hexadecimal)

%e

float (in the form d.ddd E+ dd )

Many additional conversions also can be used in the std::printf statement. See your reference manual for details.

The std::printf function does not check for the correct number of parameters on each line. If you add too many, the extra parameters are ignored. If you add too few, C will make up values for the missing parameters. Also C does not type check parameters, so if you use a %d on a floating point number, you will get strange results.

Question 16-2: Why does 2 + 2 = 5986? (Your results may vary.)

Example 16-7. two/two.c
 #include <cstdio> int main(  ) {     int answer;        answer = 2 + 2;     std::printf("The answer is %d\n");     return (0); } 

Question 16-3: Why does 21 / 7 = 0? (Your results may vary.)

Example 16-8. float3/float3.c
 #include <cstdio> int main(  ) {     float result;     result = 21.0 / 7.0;     std::printf("The result is %d\n", result);     return (0); } 

The function std::fprintf is similar to std::printf except that it takes one additional argument, the file to print to:

 std::fprintf(   file   ,   format   , p   arameter-1, parameter-   2, ...); 

Another flavor of the std::printf family is the std::sprintf call. The first parameter of std::sprintf is a C-style string. The function formats the output and stores the result in the given string:

 std::sprintf(   string   ,   format   , p   arameter-1, parameter-   2, ...); 

For example:

 char file_name[40];        /* The filename */  /* Current file number for this segment */  int file_number = 0;      std::sprintf(file_name, "file.%d", file_number);  ++file_number;  out_file = std::fopen(file_name, "w"); 

The return value of std::sprintf differs from system to system. The ANSI standard defines it as the number of characters stored in the string; however, some implementations of Unix C define it to be a pointer to the string.

16.10.2 The std::scanf Family of Input Functions

Reading is accomplished through the std::scanf family of calls. The std::scanf function is similar to std::printf in that it has sister functions: std::fscanf and std:: sscanf . The std::scanf function reads the standard input ( stdin in C terms, cin in C++ terms), parses the input, and stores the results in the parameters in the parameter list.

The format for a scanf function call is:

 number = scanf(   format, &parameter1   , . . .); 
number

Number of parameters successfully converted.

format

Describes the data to be read.

parameter1

First parameter to be read. Note the & in front of the parameter. These parameters must be passed by address.

If you forget to put & in front of each variable for std::scanf , the result can be a "Segmentation violation core dumped" or "Illegal memory access" error. In some cases a random variable or instruction will be modified. This is not common on Unix machines, but MS-DOS/Windows, with its lack of memory protection, cannot easily detect this problem. In MS-DOS/Windows, omitting & can cause a system crash.

There is one problem with this std::scanf : it's next to impossible to get the end-of-line handling right. However, there's a simple way to get around the limitations of std::scanf ”don't use it. Instead, use std::fgets followed by the string version of std::scanf , the function std::sscanf :

 char line[100];    // Line for data std::fgets(line, sizeof(line), stdin);    // Read numbers std::sscanf(line, "%d %d", &number1, &number2); 

Finally, there is a file version of std::scanf , the function std::fscanf . It's identical to scanf except the first parameter is the file to be read. Again, this function is extremely difficult and should not be used. Use std::fgets and std::sscanf instead.

I l @ ve RuBoard


Practical C++ Programming
Practical C Programming, 3rd Edition
ISBN: 1565923065
EAN: 2147483647
Year: 2003
Pages: 364

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