One More Example: Escape Sequences
Let's run one more printing example, one that makes use of some of C's special escape sequences for characters. In particular, the program in Listing 3.10 shows how the backspace (\b), tab (\t), and carriage return (\r) work. These concepts date from when computers used teletype machines for output, and they don't always translate successfully to contemporary graphical interfaces. For example, Listing 3.10 doesn't work as described on some Macintosh implementations.
Listing 3.10 The escape.c Program
/* escape.c -- uses escape characters */ #include <stdio.h> int main(void) { float salary; printf("\aEnter your desired monthly salary:");/* 1 */ printf(" $_______\b\b\b\b\b\b\b"); /* 2 */ scanf("%f", &salary); printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12.0); /* 3 */ printf("\rGee!\n"); /* 4 */ return 0; }
What Happens When the Program Runs
Let's walk through this program step by step as it would work under an ANSI C implementation. The first printf() statement (the one numbered 1) sounds the alert signal (prompted by the \a) and then prints the following:
Enter your desired monthly salary:
Because there is no \n at the end of the string, the cursor is left positioned after the colon.
The second printf() statement picks up where the first one stops, so after it is finished, the screen looks as follows:
Enter your desired monthly salary: $_______
The space between the colon and the dollar sign is there because the string in the second printf() statement starts with a space. The effect of the seven backspace characters is to move the cursor seven positions to the left. This backs the cursor over the seven underscore characters, placing the cursor directly after the dollar sign. Usually, backspacing does not erase the characters that are backed over, but some implementations may use destructive backspacing, negating the point of this little exercise.
At this point, you type your response, say 2000.00. Now the line looks like this:
Enter your desired monthly salary: $2000.00
The characters you type replace the underscore characters, and when you press Enter (or Return) to enter your response, the cursor moves to the beginning of the next line.
The third printf() statement output begins with \n\t. The newline character moves the cursor to the beginning of the next line. The tab character moves the cursor to the next tab stop on that line, typically, but not necessarily, to column 9. Then the rest of the string is printed. After this statement, the screen looks like this:
Enter your desired monthly salary: $2000.00 $2000.00 a month is $24000.00 a year.
Because the printf() statement doesn't use the newline character, the cursor remains just after the final period.
The fourth printf() statement begins with \r. This positions the cursor at the beginning of the current line. Then Gee! is displayed there, and the \n moves the cursor to the next line. Here is the final appearance of the screen:
Enter your desired monthly salary: $2000.00 Gee! $2000.00 a month is $24000.00 a year.
Flushing the Output
When does printf() actually send output to the screen? Initially, printf() statements send output to an intermediate storage area called a buffer. Every now and then, the material in the buffer is sent to the screen. The standard C rules for when output is sent from the buffer to the screen are clear: It is sent when the buffer gets full, when a newline character is encountered, or when there is impending input. (Sending the output from the buffer to the screen or file is called flushing the buffer.) For instance, the first two printf() statements don't fill the buffer and don't contain a newline, but they are immediately followed by a scanf() statement asking for input. That forces the printf() output to be sent to the screen.
You may encounter an older implementation for which scanf() doesn't force a flush, which would result in the program looking for your input without having yet displayed the prompt onscreen. In that case, you can use a newline character to flush the buffer. The code can be changed to look like this:
printf("Enter your desired monthly salary:\n"); scanf("%f", &salary);
This code works whether or not impending input flushes the buffer. However, it also puts the cursor on the next line, preventing you from entering data on the same line as the prompting string. Another solution is to use the fflush() function described in Chapter 13, "File Input/Output."