Programming in C Input / Output Formatted Console Output • In Java, formatted output is created using System.out.printf( ). • In C formatted formatted output is created using the printf( ) function. • printf( ) outputs data to the standard output device (usually the console) which is named stdout • The basic function call to printf( ) is of the form printf( format, arg1, arg2, … ) where the format is a string containing literals to be printed and conversion specifications 7/28/09 printf( ) conversions Conversions specifications begin with % and end with a conversion character. Between the % and the conversion character MAY be, in order • • • • A minus sign specifying left-justification The minimum field width A period separating the field width and precision The precision that specifies • Maximum characters for a string • Number of digits after the decimal for a floating point • Minimum number of digits for an integer • An h for “short” or an l (letter ell) for long See K&R section 7.2 and appendix section B1.2 7/28/09 Common printf( ) Conversions • %d -- the int argument is printed as a decimal number • %u -- the int argument is printed as an unsigned number • %s -- prints characters from the string (char*) until \0 is seen or the number of characters in the (optional) precision have been printed • %f -- the double argument is printed as a floating point number • %x, %X -- the int argument is printed as a hexadecimal number • %c - the int argument is printed as a single character • %p - the pointer argument is printed (implementation dependent) 7/28/09 printf( ) Examples int anInt = 5678; double aDouble = 4.123; printf(“Jim said %s\n”, “Hello Bob”); printf (“%6d is a large number\n”, anInt); printf( “The sum of %d and %8.4f is %5.2f\n”, anInt, aDouble, anInt + aDouble); /*** output ***/ Jim said Hello Bob 5678 is a large number The sum of 5678 and 4.1230 is 5682.12 7/28/09 Formatted Output Example • Use field widths to align output in columns int i; for (i = 1 ; i < 5; i++) printf("%2d %10.6f %20.15f\n", i,sqrt(i),sqrt(i)); 12 1234567890 12345678901234567890 1 1.000000 1.000000000000000 2 1.414214 1.414213562373095 3 1.732051 1.732050807568877 4 2.000000 2.000000000000000 7/28/09 Console Input In C, console input is accomplished using the scanf( ) function. scanf reads user input from the standard input device (usually the keyboard) which is named stdin Calling scanf( ) is similar to calling printf( ) scanf( format string, arg1, arg2, ... ) The format string has a similar structure to the format string in printf( ). The arguments are the addresses of the variables into which the input is store. Recall that the name of an array is synonymous with the array’s address. See K & R section 7.4 and Appendix section B1.3 for a detailed description of scanf( ) 7/28/09 scanf format string The scanf( ) format string usually contains conversion specifications that tell scanf( ) how to interpret the next input field. An “input field” is a string of non-whitespace characters. The format string usually contains – Blanks or tabs which are ignored – Ordinary characters which are expected to match the next (non-whitespace) character input by the user – Conversion specifications usually consisting • % character indicating the beginning of the conversion • An optional h, l (ell) or L • A conversion character which indicates how the input field is to be interpreted. 7/28/09 Common scanf( ) conversions • • • %d -- a decimal (integer) number %u - an unsigned decimal (integer) number %x -- a hexadecimal number – The matching arguments are of type int* – May be preceded by h to indicate that the argument is a short* or by l (ell) to indicate that the arguments is of type long* rather than int* • %s -- a word (a string delimited by white space, not a line) – The matching argument is of type char* (or char[]) – The caller must insure the array is large enough to for the input string and the terminating \0 character • %f, %e -- a floating point number with optional sign, optional decimal point, and optional exponent – The matching argument is of type float* – May be preceded by l (ell) to indicate the argument is of type double* rather than float* • %c - a single character – The matching arguments is of type char* – Does not skip over white-space 7/28/09 scanf( ) examples int age; double gpa; char name[42]; printf(“Input your name: “); scanf( “%s”, name ); printf(“Input your age: “); scanf( “%d”, &age ); printf(“ input your gpa: “); scanf (“%lf”, &gpa ); 7/28/09 /* no “&” */ gets( ) to read a line The gets( ) function is used to read a line of input from stdin until the \n character is encountered. Caller must insure that the char array is big enough to hold the input string #include <stdio.h> char myString[ 101 ]; gets( myString ); 7/28/09 Unix input redirection • By default, stdin is associated with the user’s keyboard, but Unix allows us to redirect stdin to read data from a file when your program is executed. All printf( ) statements in your program read from this file instead of the user’s keyboard, otherwise your program is unaffected. • Redirecting input from a file is useful for debugging -- you don’t have to continually retype your input. • Suppose your program’s name is Project1 and you wish to get your input from a file named data1. To redirect stdin to read from data1, use the command Project1 < data1 at the Unix prompt 7/28/09 Unix output redirection • By default, stdout is associated with the user’s console, but Unix allows us to redirect stdout to read data from a file when your program is executed. All scanf( ) statements in your program output to this file instead of the user’s console, otherwise your program is unaffected. • Suppose your program’s name is Project1 and you wish to write your output to a file named logfile1. To redirect stdout to write to logfile1, use the command Project1 > logfile at the Unix prompt • Can you redirect both input and output? 7/28/09 Text File I/O • Reading and writing from/to a text file is similar to getting input from stdin (with printf) and writing to stdout (with scanf). • Reading data from a text file is accomplished with the function fscanf( ). This function works the same as scanf( ), but requires an additional parameter which is a handle to the file. • Reading a line from a text file is accomplished using the fgets( ) function. This function is similar to gets( ) but requires a handle to a file and a max character count. • Similarly, writing to a text file is accomplished with the function fprintf() which works the same as printf( ), but also requires a handle to the file to be read. • In fact, printf( ) and scanf( ) are just specialized versions of fprintf( ) and fscanf( ) respectively. 7/28/09 Opening and Closing To read or write from a text file using fscanf( ), fegets( ) or fprintf( ), the file must first be opened using fopen( ). The file should be closed using fclose( ) when all I/O is complete. fopen( ) returns a handle to the file as the type FILE* (a pointer to a FILE struct) which is then used as the argument to fscanf(), fgets( ), fprintf( ) and fclose( ). The return value from fopen( ) should be checked to insure that the file was in fact opened. 7/28/09 fscanf.c #include <stdio.h> #include <stdlib.h> int main ( ) { double x ; FILE *ifp ; /* exit */ /* try to open the file for reading, check if successful */ /* if it wasn't opened exit gracefully */ ifp = fopen("test_data.dat", "r") ; if (ifp == NULL) { printf ("Error opening test_data.dat\n"); exit (-1); } fscanf(ifp, "%lf", &x) ; /* read one double from the file */ fclose(ifp); /* close the file when finished */ /* check to see what you read */ printf("x = %.2f\n", x) ; return 0; } 7/28/09 fgets( ) #include <stdio.h> #include <stdlib.h> /* exit */ int main ( ) { double x ; FILE *ifp ; char myLine[42 + 1 ]; /* + 1 for terminating \0 */ ifp = fopen("test_data.dat", "r") ; fgets(myLine, 42, ifp ); /* read up to 42 chars*/ fclose(ifp); /* close the file when finished */ /* check to see what you read */ printf(”myLine = %s\n”, myLine); return 0; } 7/28/09 Detecting end-of-file with fscanf • When reading an unknown number of data elements from a file using fscanf( ), we need a way to determine when the file has no more data to read, i.e, we have reached the “end of file”. • Fortunately, the return value from fscanf( ) holds the key. fscanf( ) returns an integer which is the number of data elements read from the file. If end-of-file is detected the integer return value is the special value EOF 7/28/09 EOF example code /* code snippet that reads an undetermined number of integer student ages from a file and prints them out as an example of detecting EOF*/ FILE *inFile; inFile = fopen( “myfile”, “r” ); /* check that the file was opened */ int age; while ( fscanf(infile, “%d”, &age ) != EOF ) printf( “%d\n”, age ); fclose( inFile ); 7/28/09 Detecting EOF with fgets( ) • fgets( ) returns the memory address in which the line was stored (the char array provided). However, when fgets( ) encounters EOF, the special value NULL is returned. FILE *inFile; inFile = fopen( “myfile”, “r” ); /* check that the file was opened */ char string[120 + 1]; while ( fgets(string, 120, inFile ) != NULL ) printf( “%s\n”, string ); fclose( inFile ); 7/28/09 fprintf.c /* fprintf.c */ #include <stdio.h> #include <stdlib.h> /* exit */ int main ( ) { double pi = 3.14159 ; FILE *ofp ; /* try to open the file for writing, check if successful */ /* if it wasn't exit gracefully */ ofp = fopen("test.out", “w") ; if (ofp == NULL) { printf ("Error opening test.out\n"); exit (-1); } /* write to the file using printf formats */ fprintf(ofp, “Hello World\n”); fprintf(ofp, “PI is defined as %6.5lf\n”, pi); fclose(ofp); return 0; } 7/28/09 /* close the file when finished reading */ fprintf vs printf fscanf vs scanf • Function prototypes are identical except that fprintf and fscanf require FILE* parameter • Format strings identical • fscanf, fprintf are more general • printf can be written using fprintf – fprintf( stdout, ....) • Similarly, scanf can be written using fscanf – fscanf( stdin, .... ) 7/28/09 sprintf • Sometimes its necessary to format a string within your program – Compose an email – Compose a message sent to another computer – Format a system command to be executed • The sprintf( ) function formats a string using all the same printf formatting conversions but stores the formatted string into the specified character array. char message[ 44 ]; int age = 42; sprintf(message, “My age is %2d\n”, age); 7/28/09