C-Style Conversion Routines
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, parameter-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.
|
|
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.
|
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.dddE+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.
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);}
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, parameter-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, parameter-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");
WARNING: The return value of
std::sprintfdiffers 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.
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, ¶meter1, . . .);
- 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.
WARNING: 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 datastd::fgets(line, sizeof(line), stdin); // Read numbersstd::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.

Comments
There are no comments yet. Be the first to comment!