Introduction to Computer and Program Design Lesson 7 Standard I/O in C and C++ James C.C. Cheng Department of Computer Science National Chiao Tung University
Standard I/O in C There three I/O memory buffers in the computer FILE* stdin For the standard input device (generally, a keyboard). FILE* stdout For the standard output device (generally, the screen). FILE* stderr For output error and warning messages to the standard output device FILE* is a pointer to point a stream I/O buffer FILE* stdin address data 0x 26E81E00 26E81E00 04 A5 00 10 26E81E04 0B 00 56 4F 26E81E08 06 FF 00 00 26E81E0C B4 00 C7 FF 2
Standard I/O in C putchar() put a character to stdout Usage: #include <stdio.h> int putchar( int c ); Print c by ASCII returns the printed character Ex: ASCII: American Standard Code for Information Interchange putchar('a'); putchar('b'); putchar('c'); putchar('\n'); /* ABC */ 3
Standard I/O in C printf() Put a formatted string of characters to the stdout. Usage: #include <stdio.h> int printf( const char *format [, argument]... ); returns the number of characters printed The results are undefined if there are not enough arguments for all the format specifications. Example: int x = 65; float r = 1.2f; printf("%d\t%d\t%d\n", x, x+1, x+2); /* 65 66 67 */ printf("%x\\%x\\%x\n", x, x+1, x+2); /* 41\42\43 */ printf( \"%c%c%c\" \n", x, x+1, x+2); /* "ABC" */ printf( %f, %f, %f \n", r, r+0.1f, r+0.2f); /* 1.200000, 1.300000, 1.400000 */ Escape characters (Special function characters): \n newline \t tab \r return \' single quotation \ double quotation \\ backslash \ooo ASCII in octal \xhhh ASCII in hex 4
Standard Output in C printf() Basic Format Specification: float r = 0.00000123; printf("%f, %E, %G\n", r, r, r); printf("%f, %e, %g\n", r, r, r); Output: 0.000001, 1.230000E-006, 1.23E-006 0.000001, 1.230000e-006, 1.23e-006 Notice that E(or e) means power of 10, not power of 2.71828 5
Standard Output in C printf() %+width+.precision + {f/e/e/g/g}, width: the minimum number of characters printed, if width is not given, all characters of the value are printed. precision: for f/e/e : the number of digits after the decimal point, for g/g: the maximum number of significant digits printed. default is six float r = 0.00000123; printf("%10.8f, %4.2e, %4.2g\n", r, r, r); Output: 0.00000123, 1.23e-006, 1.2e-006 6
Standard Output in C printf() Data alignment The memory pre-allocation for each argument: 4-byte arguments: bool, char, int, short, long 8-byte arguments: int x = 10; float r = 0.123f; char c = 65; float, double float r = 0.123f; printf("%f, r); /* 1. Allocate 8 byte to store the vlaue of r float -> double 2. %f will convert the double float to string */ printf("%d, %f, %d, %d\n", x, c, c, x+1, x+2); // Why dose c need to be printed twice? printf("%f, %d%d, %f, %f\n", r, r, r + 1, r + 2); // Why does it print the second r by %d%d? 7
Standard Output in C printf() Type cast all float arguments are promoted to double bool, (unsigned)char, (unsigned)short, and (unsigned)int are promoted to (unsigned)long ex unsigned char a = -1; printf("%08x\n", a); int b = -1; printf("%08x\n", b); float f = 0.1f; printf("%x\n", f); printf("%x%x\n", f); // 000000FF // FFFFFFFF // A0000000 // A00000003FB99999 0.1 10 = 0.00011 2 in IEEE 754 32 bit format 0, 01111011, 10011001100110011001101 = 3DCCCCCD 16 Then, promotion to 64 bit 0, 01111111011, 1001100110011001100110100 0 = 3FB99999A0000000 16 8
Standard Input in C scanf() Read formatted data from the standard input stream, the stdin. Usage: #include <stdio.h> int scanf( const char *format [,argument]... ); the format represents that the input format of the stdin White-space characters, WC: blank (' '); tab ('\t'); or newline ('\n'). scanf will read and ignore any WCs which are encountered before the next non-wc from stdin. The non-wcs in format, except the % scanf will read the next character from stdin and compart it to the non-wc. If they are matched, the input character is discarded and the scanf continues. If they are different, the scanf fails, returning and leaving subsequent characters of stdin unread If there is no any non-wc after the last % in the format, then all of the input WCs after the last % will be left in stdin 9
Standard Input in C The return of scanf() 1. The number of fields successfully converted and assigned. ex: int a =1, b =2, c =3; printf("%d\n", scanf("%d %d %d", &a, &b, &c) ); printf("%d, %d, %d", a, b, c); If you input 5 6 7, you will see 3 5, 6, 7 If you input 5 6 x, you will see 2 5, 6, 3 If you input 5 x 7, you will see 1 5, 2, 3 10
Standard Input in C The return of scanf() 2. EOF End of File usually EOF is defined by (-1) In Windows, using Ctrl+z to input an EOF character. In UNIX, using Ctrl+d to input an EOF character. In Windows, scanf() returns EOF if the first input is Ctrl+z. In Unix, scanf() returns EOF if the first input is Ctrl+d. ex: int n = 0; printf("n = (Ctrl+Z to exit)"); while( scanf("%d", &n)!= EOF ){ if (n & 1) printf("%d is odd\n", n) else printf("%d is even\n", n); printf("n = (Ctrl+Z to exit)"); } 11
Standard Input in C scanf() Datatype Specification: Example : float r = 0.0f; double s = 0.0; scanf("%d", &r); printf("f = %f\n", r); scanf("%f", &r); printf("f = %f\n", r); scanf("%f", &s); printf("f = %lf\n", s); scanf("%lf", &s); printf("f = %lf\n", s); 12
Standard Input in C scanf() Confusion with White Space : int a=0, R=0; R = scanf("%d", &a); getchar(); // Never stop here! int a=0, b =0, c=0, R=0; R = scanf("%d", &a); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); R = scanf(" %d", &b); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); R = scanf("%d ", &c); //?? printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); int a=0, b =0, c=0, R=0; // No difference between these two scanf R = scanf("%d%d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); R = scanf(" %d \t %d \n %d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); 13
Standard Input in C scanf() Are these two format specifiers different? int a=0, b =0, c=0, R=0; R = scanf("%d:%d:%d", &a, &b, &c); // bad format! // Try to type 1 :2 :3 printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); int a=0, b =0, c=0, R=0; R = scanf("%d\t:%d\t:%d", &a, &b, &c); // Good format // Try to type 1 : 2 : 3 printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); int a=0, b =0, c=0, R=0; R = scanf("%d\t:\t%d\t:\t%d", &a, &b, &c); // redundant format! // Try to type 1 : 2 : 3 printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); 14
Standard Input in C scanf() %*: Read but not store int a=0, b =0, c=0, R=0; R = scanf("%d%d%*d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); // In legal input string, c will always be zero! * int a=0, b =0, c=0, R=0; R = scanf("%d%*d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); // In legal input string, c will always be zero! int a=0, b =0, c=0, R=0; R = scanf("%*d%d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); // In legal input string, c will always be zero! 15
Standard Input in C Using scanf() to read a text string char A[20] = {0}; // Declare a string of 20 zero characters scanf("%s", A); // What if we type ABC EFG XYZ printf("%s\n", A); char A[20] = {0}, B[20] = {0}, C[20] = {0}; scanf("%s %s %s", A, B, C); // Try it again printf("%s %s %s\n", A, B, C); %[ ]: Read the specified characters Input ends when a non-matching character is reached or the field width is reached. char A[20] = {0}, B[20] = {0}, C[20] = {0}; scanf("%[0-9]%[a-z]%[a-z]", A, B, C); printf("%s %s %s\n", A, B, C); scanf("%[ -~, '\t']", A); // Read the characters which ASII are 9 and 32 to 126 printf("%s\n", A); scanf( %[ -~, \t, \n ], A); // Oops. 16
Standard Input in C Using scanf() to read a text string %[^ ]: Read the characters except the specified characters char A[20] = {0}, B[20] = {0}, C[20] = {0}; scanf("%[^0-9]%[^a-z]%[^a-z]", A, B, C); printf("%s %s %s\n", A, B, C); scanf("%[^'\n']", A); // Read all characters except \n printf("%s\n", A); 17
Standard Input in C stdin should be cleared before using "%[]" to input a string because: int x; char str[10] = {0}; scanf("%d",&x); // After you type "123" + ENTER, then "123"x and stdin = "\n" cout << x << endl; scanf("%[0-9]",ori); // Oops! the first character in stdin is '\n', not '0' '9', and causes scanf failed! cout << ": " << ori << endl; 18
Standard I/O in C getchar() read a character from stdin Usage: #include <stdio.h> int getchar( void ); Returns the input character Ex: int c = getchar(); 19
Standard I/O in C ungetc() pushes a character back onto a data stream. Usage: #include <stdio.h> int ungetc( int chr, FILE * stream); chr: the character to be pushed stream: the target data stream If successful, it returns chr, otherwise returns EOF (-1) Ex: ungetc( \n, stdin); 20
Standard Input in C How to clear the stdin? Method 1: int a=0, b =0, c=0, R=0; R = scanf("%d%d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); getchar(); // It just clear one character that is kept in stdin Method 2: Method 3: int a=0, b =0, c=0, R=0; R = scanf("%d%d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); { int c; while((c=getchar())!='\n'&&c!=eof); } //EOF = (-1) /* The best method since it can clear all characters in stdin but needs high computational cost. */ int a=0, b =0, c=0, R=0; R = scanf("%d%d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); v // Read all characters, except \n, from stdin getchar(); // Read the last \n // Maybe fail in sscanf 21
Standard Input in C How to clear the stdin? DO NOT use fflush(stdin) to clear stdin! Since the C standard does not define it. int a=0, b =0, c=0, R=0; R = scanf("%d%d%d", &a, &b, &c); printf("a=%d, b=%d, c=%d and R=%d\n", a, b, c, R); fflush(stdin); 22
Standard Input in C sscanf() #include <stdio.h> int sscanf( const char *buffer, const char *format [, argument ]... ); where the buffer is the input string The difference between the scanf and sscanf is that the input buffer of sscanf is an array of characters, not the stdin. Besides the input buffer, the usage of sscanf is the same as scanf 23
Standard Output in C++ Let s print some variables #include <stdio.h> int main(){ int x = 10; double y = 1.234; char *s = "Hello world"; printf("%d, %f, %s\n", x, y, s); } #include <iostream> int main(){ int x = 10; double y = 1.234; char *s = "Hello world"; std::cout.precision(7); std::cout << x << ", " << y << ","; std::cout << s << std::endl; } or #include <iostream> using namespace std; int main(){ int x = 10; double y = 1.234; char *s = Hello world ; cout.precision(7); cout << x << ", " << y << ","; cout << s << endl; } 24
Standard Output in C++ Namespace Scope operator Left object std::cout << x; Insertion operator (a binary operator) It means that put the x into the stdout cout is an object that represents the stdout Right object To save typing, we can use the using namespace command. std::cout.precision(7); Object Member method Member-selection operator 25
Standard Output in C++ The manipulators of cout int x =255; std::cout << std::oct ; std::cout << x << std::endl; // 377 std::cout << std::dec ; std::cout << x << std::endl; // 255 std::cout << std::showbase << std::hex << x << std::endl ; // 0xff std::cout << std::uppercase << x << std::endl ; // 0xFF std::cout << std::noshowbase; std::cout.width(10); std::cout << std::dec << x << std::endl; // 255 std::cout.width(10); std::cout << std::right << x << std::endl; // 255 std::cout.width(10); std::cout << std::left << x << "!" << std::endl; // 255! float y = 123.56789; std::cout.precision(5); std::cout << y << std::endl; //123.57 26
Standard Output in C++ The list of manipulators boolalpha - Insert or extract bool objects as "true" or "false". noboolalpha - Insert or extract bool objects as numeric values. fixed - Insert floating-point values in fixed format. scientific - Insert floating-point values in scientific format. internal - Internal-justify. left - Left-justify. right - Right-justify. dec - Insert or extract integer values in decimal format. hex - Insert or extract integer values in hexadecimal (base 16) format. oct - Insert or extract values in octal (base 8) format. 27
Standard Output in C++ The list of manipulators noshowbase - Do not prefix value with its base. showbase - Prefix value with its base. noshowpoint - Do not show decimal point if not necessary. showpoint - Always show decimal point when inserting floating-point values. noshowpos - Don't insert plus sign (+) if number >= 0. showpos - Do insert plus sign (+) if number >=0. noskipws - Do not skip initial white space on extracting. skipws - Skip initial white space on extracting. nouppercase - Don't replace lowercase letters by uppercase equivalents. uppercase - Replace lowercase letters by uppercase equivalents. unitbuf - Flush buffer after an insert. nounitbuf - Don't flush buffer after each insert. 28
Standard Output in C++ ios::flags setf( long ) and unsetf( long), to set and unset the flag. Using flags() to recover all setting int x =255; long OrgFlag = std::cout.flags(); // Record the origin setting std::cout.unsetf( ios::dec ); // unset std::cout.setf( ios::oct ); std::cout << x << std::endl; // 0377 std::cout.unsetf( ios::oct ); // unset std::cout.setf( ios::dec ); std::cout << x << std::endl; // 255 std::cout.unsetf( ios::dec ); // unset std::cout.setf( ios::hex ios::showbase ios::uppercase ); std::cout << x << std::endl; // 0xFF std::cout.flags( OrgFlag ); std::cout << x << std::endl; // Recover the flag 29
Standard Input in C++ std::cin with the extraction operator, >> cin is an object that represents the stdin char c1=0, c2 =0, c3=0; std::cin >> c1 >> c2; std::cout << c1 << ", " << c2 << std::endl; std::cin >> c3; std::cout << c3 << std::endl; Notice that the delimit characters are white space keys.
Standard Input in C++ Conversion failure It will stop immediately int x = 10; std::cin >> x; // Try to type xyz\n std::cout << x << std::endl; // 10 The solution is do{ std::cin.clear(); // Clear the last conversion state std::cin >> x ; { int c; while((c=getchar())!='\n'&&c!=eof); } // Clear the input buffer } while( std::cin.fail() ); // Check the conversion state std::cout << x << std::endl;