C
C
output of 12345 from line 14. This means that when the minimum field width is shorter than the width of the ou tput, the latter is taken, and the output is still printed in full. Aligning Output As you might have noticed in the previous section, all output is right-justified . In other words, by default, all output is placed on the right edge of the field, as long as the field width is longer than the width of the output. You can change this and force output to be left-justified. To do so, you need to prefix the minimum field specifier with the minus sign (-). For example, %-12d specifies the minimum field width as 12, and justifies the output from the left edge of the field. Listing 5.7 gives an example of aligning output by left- or right-justification. TYPE Listing 5.7. Left- or right-justified output. 1: /* 05L07.c: Aligning output */ 2: #include <stdio.h> 3: 4: main() 5: { 6: int num1, num2, num3, num4, num5; 7: 8: num1 = 1; 9: num2 = 12; 10: num3 = 123; 11: num4 = 1234; 12: num5 = 12345; 13: printf("%8d %-8d\n", num1, num1); 14: printf("%8d %-8d\n", num2, num2); 15: printf("%8d %-8d\n", num3, num3); 16: printf("%8d %-8d\n", num4, num4); 17: printf("%8d %-8d\n", num5, num5); 18: return 0; 19: } OUTPUT I get the following output displayed on the screen after I run the executable 05 L07.exe from a DOS prompt on my machine: C:\app> 05L07 1 1 12 12 123 123 1234 1234 12345 12345 C:\app> ANALYSIS In Listing 5.7, there are five integer variables, num1, num2, num3, num4, and nu m5, that are declared in line 6 and are assigned values in lines 8_12. These values represented by the five integer variables are then printed out by t he printf() functions in lines 13_17. Note that all the printf() functions have the same first argument: "%8d %-8d\n". Here the first format specifier, %8d, aligns the output at the right edge of the field, and the second specifier, %-8d , does the alignment by justifying the output from the left edge of the field. After the execution of the statements in lines 13_17, the alignment is accomplis
hed and the output is put on the screen like this: 1 1 12 12 123 123 1234 1234 12345 12345 Using the Precision Specifier You can put a period (.) and an integer right after the minimum field width spec ifier. The combination of the period (.) and the integer makes up a precision specifier. The precision specifier is a nother important specifier you can use to determine the number of decimal places for floating-point numbers, or to specify the maximum field width (or length) for integers or strings. (Strings in C are introduced in Hour 13, "Manipulating Strings.") For instance, with %10.3f, the minimum field width length is specified as 10 cha racters long, and the number of decimal places is set to 3. (Remember, the default number of decimal places is 6 .) For integers, %3.8d indicates that the minimum field width is 3, and the maximum field width is 8. Listing 5.8 gives an example of left- or right-justifying output by using precis ion specifiers. TYPE Listing 5.8. Using precision specifiers. 1: /* 05L08.c: Using precision specifiers */ 2: #include <stdio.h> 3: 4: main() 5: { 6: int int_num; 7: double flt_num; 8: 9: int_num = 123; 10: flt_num = 123.456789; 11: printf("Default integer format: %d\n", int_num); 12: printf("With precision specifier: %2.8d\n", int_num); 13: printf("Default float format: %f\n", flt_num); 14: printf("With precision specifier: %-10.2f\n", flt_num); 15: return 0; 16: } OUTPUT After running the executable file 05L08.exe on my machine, I get the following o utput on the screen: C:\app> 05L08 Default integer format: 123 With precision specifier: 00000123 Default float format: 123.456789 With precision specifier: 123.46 C:\app> ANALYSIS The program in Listing 5.8 declares one integer variable, int_num, in line 6, an d one floating-point number, flt_num, in line 7. Lines 9 and 10 assign 123 and 123.456789 to int_num and flt_num, respectively. In line 11, the default integer format is specified for the integer variable, in t_num, while the statement in line 12 specifies the integer format with a precision specifier that indicates that the maximum field width is 8 characters long.
Therefore, you see that five zeros are padded prior to the integer 123 in the se cond line of the output. For the floating-point variable, flt_num, line 13 prints out the floating-point value in the default format, and line 14 reduces the decimal places to two by putting the precision specifier .2 within t he format specifier %-10.2f. Note here that the left-justification is also specified by the minus sign (-) in the float ing-point format specifier. The floating-point number 123.46 in the fourth line of the output is produced by the statement in line 14 with the precision specifier for two decimal places. Therefore, 123.456789 rounded to two decimal places becomes 123.46. Summary In this lesson you've learned the following: ? The C language treats a file as a series of bytes. ? stdin, stdout, and stderr are three file streams that are pre-opened for you t o use. ? The C library functions getc() and getchar() can be used to read in one charac ter from the standard input. ? The C library functions putc() and putchar() can be used to write one characte r to the standard output. ? %x or %X can be used to convert decimal numbers to hex numbers. ? A minimum field width can be specified and ensured by adding an integer into a format specifier. ? An output can be aligned at either the left or right edge of the output field. ? A precision specifier can be used to specify the decimal place number for floa ting-point numbers, or the maximum field width for integers or strings. In the next lesson you'll learn about some important operators in C. Q&A Q What are stdin, stdout, and stderr? A In C, a file is treated as a series of bytes that is called file stream. stdin , stdout, and stderr are all preopened file streams. stdin is the standard input for reading; stdout is the standard ou tput for writing; stderr is the standard error for outputting error messages. Q How much is the hex number 32? A Hexadecimal, or hex for short, is a base-16 numerical system. Therefore, 32 (h ex) is equal to 3*161+2*160, or 50 in decimal. Q Are getc(stdin) and getchar() equivalent? A Because the getchar() function reads from the file stream stdin by default, ge tc(stdin) and getchar() are equivalent. Q In the function printf("The integer %d is the same as the hex %x", 12, 12), wh at is the relationship between the format specifiers and the expressions? A The two format specifiers, %d and %x, specify the formats of numeric values co ntained in the expression section. Here the first numeric value of 12 is going to be printed ou t in integer format, while the second 12 (in the expression section) will be displayed in the hex format. G enerally speaking, the number of format specifiers in the format section should match the number of exp ressions in the expression section. Workshop To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish the exercises provided in the Workshop before you move to the next lesson. The a
nswers and hints to the questions and exercises are given in Appendix E, "Answers to Quiz Questions and Exercises. " Quiz 1. Can you align your output at the left edge, rather than the right edge, of th e output field? 2. What is the difference between putc() and putchar()? 3. What does getchar() return? 4. Within %10.3f, which part is the minimum field width specifier, and which one is the precision specifier? Exercises 1. Write a program to put the characters B, y, and e together on the screen. 2. Display the two numbers 123 and 123.456 and align them at the left edge of th e field. 3. Given three integers 15, 150, and 1500 write a program that prints the integers o n the screen in the hex format. 4. Write a program that uses getchar() and putchar() to read in a character ente red by the user and write the character to the screen. 5. If you compile the following C program, what warning or error messages will y ou get? main() { int ch; ch = getchar(); putchar(ch); return 0; } Previous | Table of Contents | Next Sams Teach Yourself C in 24 Hours Previous | Table of Contents | Next Hour 6 - Manipulating Data with Operators "The question is," said Humpty Dumpty, "which is to be master that's all." L. Carroll You can think of operators as verbs in C that let you manipulate data. In fact, you've learned some operators, such as + (addition), - (subtraction), * (multiplication), / (division), and % (remainde r), in Hour 3, "The Essentials of C Programs." The C language has a rich set of operators. In this hour, you'll lear n about more operators, such as ? Arithmetic assignment operators ? Unary minus operators ? Increment and decrement operators ? Relational operators ? Cast operator Arithmetic Assignment Operators Before jumping into the arithmetic assignment operators, you first need to learn more about the assignment operator. The Assignment Operator (=) In the C language, the = operator is called an assignment operator, which you've seen and used for several hours. The general statement form to use an assignment operator is left-hand-operand = right-hand-operand; Here the statement causes the value of the right-hand-operand to be assigned (or written) to the memory location of the left-hand-operand. Additionally, the assignment statement itself returns the same value that is assigned to the lefthandoperand. For example, the a = 5; statement writes the value of the right-hand operand (5) into the memory location of the
integer variable a (which is the left-hand operand in this case). Similarly, the b = a = 5; statement assigns 5 to the integer variable a first, a nd then to the integer variable b. After the execution of the statement, both a and b contain the value of 5. Combining Arithmetic Operators with = Consider this example: Given two integer variables, x and y, how do you assign t he sum of x and y to another integer variable, z? By using the assignment operator (=) and the addition operator (+), you get the following statement: WARNING Don't confuse the assignment operator (=) with the relational operator, == (call ed the equal-to operator). The == operator is introduced later in this hour. z = x + y; As you can see, it's pretty simple. Now, consider the same example again. This t ime, instead of assigning the result to the third variable, z, let's write the sum back to the integer variable, x: x = x + y; Here, on the right side of the assignment operator (=), the addition of x and y is executed; on the left side of =, the previous value saved by x is replaced with the result of the addition from the r ight side. The C language gives you a new operator, +=, to do the addition and the assignme nt together. Therefore, you can rewrite the x = x + y; statement to x += y; The combinations of the assignment operator (=) with the arithmetic operators, + , -, *, /, and %, give you another type of operators arithmetic assignment operators: The following shows the equivalence of statements: x += y; is equivalent to x = x + y; x -= y; is equivalent to x = x - y; x *= y; is equivalent to x = x * y; x /= y; is equivalent to x = x / y; x %= y; is equivalent to x = x % y; Note that the statement z = z * x + y; is not equivalent to the statement z *= x + y; because z *= x + y is indeed the same as z = z * (x + y); Listing 6.1 gives an example of using some of the arithmetic assignment operator s. TYPE Listing 6.1. Using arithmetic assignment operators. Operator Description += Addition assignment operator -= Subtraction assignment operator *= Multiplication assignment operator /= Division assignment operator %= Remainder assignment operator 1: /* 06L01.c: Using arithmetic assignment operators */ 2: #include <stdio.h> 3: 4: main() 5: { 6: int x, y, z;
7: 8: x = 1; /* initialize x */ 9: y = 3; /* initialize y */ 10: z = 10; /* initialize z */ 11: printf("Given x = %d, y = %d, and z = %d,\n", x, y, z); 12: 13: x = x + y; 14: printf("x = x + y assigns %d to x;\n", x); 15: 16: x = 1; /* reset x */ 17: x += y; 18: printf("x += y assigns %d to x;\n", x); 19: 20: x = 1; /* reset x */ 21: z = z * x + y; 22: printf("z = z * x + y assigns %d to z;\n", z); 23: 24: z = 10; /* reset z */ 25: z = z * (x + y); 26: printf("z = z * (x + y) assigns %d to z;\n", z); 27: 28: z = 10; /* reset z */ 29: z *= x + y; 30: printf("z *= x + y assigns %d to z.\n", z); 31: 32: return 0; 33: } OUTPUT After this program is compiled and linked, an executable file is created. On my machine, this executable file is named as 06L01.exe. The following is the output printed on the screen af ter I run the executable from a DOS prompt: C:\app> 06L01 Given x = 1, y = 3, and z = 10, x = x + y assigns 4 to x; x += y assigns 4 to x; z = z * x + y assigns 13 to z; z = z * (x + y) assigns 40 to z; z *= x + y assigns 40 to z. C:\app> ANALYSIS