310 likes | 435 Views
Chapter 17 - I/O in C. Concepts to Learn…. Standard Libraries Input/Output Data Streams printf() scanf() Variable Argument Lists File I/O fprintf and fscanf sprintf and sscanf. Standard Libraries. C Standard Library. Standard libraries promote cross-platform compatibility.
E N D
Concepts to Learn… • Standard Libraries • Input/Output • Data Streams • printf() • scanf() • Variable Argument Lists • File I/O • fprintf and fscanf • sprintf and sscanf Input and Output
Standard Libraries C Standard Library • Standard libraries promote cross-platform compatibility. • Useful for building complex programs. • Functions, types, and macros of the standard library are accessed by the #include directive. • Headers may be included in any order (and any number of times). • Actual I/O libraries can be linked statically or dynamically. Input and Output
Standard Libraries ANSI Standard Libraries • <assert.h> Diagnostics • <ctype.h> Character Class Tests • <errno.h> Error Codes Reported by (Some) Library Functions • <float.h> Implementation-defined Floating-Point Limits • <limits.h> Implementation-defined Limits • <locale.h> Locale-specific Information • <math.h> Mathematical Functions • <setjmp.h> Non-local Jumps • <signal.h> Signals • <stdarg.h> Variable Argument Lists • <stddef.h> Definitions of General Use • <stdio.h> Input and Output • <stdlib.h> Utility functions • <string.h> String functions • <time.h> Time and Date functions Input and Output
Input/Output Input/Output • Most programs require an input and output. • I/O is not directly supported by C. • I/O is handled by a set of standard library functions defined by the ANSI C standard. • The stdio.h header file contains function declarations for I/O and preprocessor macros related to I/O. • stdio.h does not contain the source code for I/O library functions! Input and Output
Data Streams I/O Data Streams • All C character based I/O is performed on streams. • All I/O streams must be opened and closed • A sequence of characters received from the keyboard is an example of a text stream • In standard C there are 3 streams automatically opened upon program execution: • stdin is the input stream • stdout is the output stream • stderr stream for error messages Input and Output
Data Streams I/O Data Streams • One character at a time: • int putc(int character, FILE* stream); • #define putchar(c) putc(c,stdout) char c = 'h'; putchar(c); putchar('h'); putchar(104); • int getc(FILE* stream); • #define getchar() getc(stdin) char c; c = getchar(); Input and Output
Data Streams I/O Data Streams • On most computer systems, stdin and stdout I/O streams are buffered. • A buffer is a temporary storage area • Every character sent to the keyboard input stream is captured by the computer’s low-level software and kept in a buffer until it is released to the input stream. • Allows editing of typed characters. • The keyboard input buffer holds keystrokes until the input line is terminated by the enter (\n) key. • After the enter key is pressed, the program can see the characters typed. Input and Output
printf() Formatted Output • The printf function outputs formatted values to the stdout stream using putc printf( const char *format, ... ); • The format string contains two object types: • Ordinary characters that are copied to the output stream • Conversion specifications which cause conversion and printing of the next argument in the argument list. printf("\nX = %d, Y = %d", x, y); Conversion specifications Characters Input and Output
printf() Formatted Output • Each conversion specification begins with a % and ends with a conversion character: • Integer "%d" • String "%s" • Character "%c" • Formatting options are inserted between the % and the conversion character: • Field width "%4d" • Length modifier "%ld" • Left justified "%-4d" • Zero padded "%04d" Input and Output
printf() Formatted Output • Common conversion specifications: • Decimal "%d" or "%i" • String "%s" • Character "%c“ • Hexadecimal "%x" • Unsigned decimal "%u" • Floating point "%f" • Scientific notation "%e" • Pointer "%p" • % "%%" Input and Output
printf() Formatted Output • A period is used to separate the field width from the precision when formatting floating point numbers: printf("Speed = %10.2f", speed); • A variable field width may be specified using an asterisk (*) formatting option. The value is computed by converting the next argument (which must be an int): printf("%.*s", max, s); Input and Output
printf() Formatted Output • Variable field width example: #include <stdio.h> int main(void) { const char text[] = "Hello world"; int i; for ( i = 1; i < 12; ++i ) { printf("\"%.*s\"\n", i, text); } return 0; } /* my output "H" "He" "Hel" "Hell" "Hello" "Hello " "Hello w" "Hello wo" "Hello wor" "Hello worl" "Hello world" */ Input and Output
printf() Formatted Output • Certain characters cannot be easily representedby a single keystroke, because they • correspond to whitespace (newline, tab, backspace, return...) • are used as delimiters for other literals (quote, double quote, backslash, ...) • special functions Input and Output
printf() Formatted Output int a = 100; int b = 65; char c = 'z'; char banner[ ] = "Hola!"; double pi = 3.14159; printf("The variable 'a' decimal: %d\n", a); printf("The variable 'a' hex: %x\n", a); printf("'a' plus 'b' as character: %c\n", a+b); printf("A char %c.\t A string %s\n A float %7.4f\n", c, banner, pi); Input and Output
printf() Formatted Output • What happens when you don't provide adata argument for every formatting character? printf("\nThe value of nothing is %d"); • %d will convert and print whatever is on the stack in the position where it expects to find the first argument. • Something will be printed, but it will be garbage or whatever is next in the stack. Input and Output
scanf() Formatted Input • The function scanf is similar to printf, providing many of the same conversion facilities in the opposite direction: scanf( const char *format, ... ); • reads characters from the standard input (stdin), • interprets them according to the specification in format, • stores the results through the remaining arguments. • The format argument is a string; all other arguments must be a pointers indicating where the corresponding converted input should be stored. Input and Output
scanf() Formatted Input • Common input conversion specifications: • Decimal "%d" or "%i" • String "%s" • Character "%c“ • Hexadecimal "%x" • Unsigned decimal "%u" • Floating point "%f" Input and Output
scanf() scanf Conversion • For each data conversion, scanf will skip whitespace characters and then read ASCII characters until it encounters the first character that should NOT be included in the converted value. %d Reads until first non-digit. %x Reads until first non-digit (in hex). %s Reads until first whitespace character. • Literals in format string must match literals in theinput stream. • Data arguments must be pointers, because scanfstores the converted value to that memory address. Input and Output
Doesn't match literal '/', so scanf quitsafter second conversion. scanf() scanf Return Value • The scanf function returns an integer, which indicates the number of successful conversions performed. • This lets the program check whether the input streamwas in the proper format. • Example:scanf("%s %d/%d/%d %lf", name, &bMonth, &bDay, &bYear, &gpa); Input StreamReturn ValueMudd 02/16/69 3.02 5 Muss 02 16 69 3.02 2 Input and Output
scanf() Formatted Input • scanf returns the number of successfully matched and assigned input items i = scanf("%d/%d/%d", &mon, &day, &yr); • What’s wrong with the following? int n = 0; scanf("%d", n); • Of course, the argument is not a pointer! • scanf will use the value of the argument as an address • What about a missing data argument? scanf("%d"); • scanf will get an address from stack, where it expects tofind first data argument - if you're lucky, the program will crash trying to modify a restricted memory location. Input and Output
Variable Argument Lists Variable Argument Lists • The number of arguments in a call to printf or scanf depends on the number of data items being read or written. • Declaration of printf (from stdio.h) int printf(const char*, ...); • Parameters pushed on the stack from right to left. • This stack-based calling convention allows fora variable number of arguments to be easily handled. Input and Output
Variable Argument Lists Variable Argument Lists #include <stdio.h> #include <stdarg.h> #define PRINT_BUFFER_SIZE 32 //************************************************************** // formatted printf to lcd // void lcd_printf(char* fmt, ...) { va_list arg_ptr; char pBuffer[PRINT_BUFFER_SIZE]; char* s_ptr = pBuffer; if (strlen(fmt) > PRINT_BUFFER_SIZE) ERROR2(SYS_ERR_PRINT); va_start(arg_ptr, fmt); // create ptr to args vsprintf(s_ptr, fmt, arg_ptr); // create print string while (*s_ptr) lcd_putchar(*s_ptr++); // output string va_end(arg_ptr); // reset ptr to null return; } // end lcd_printf Input and Output
File I/O I/O from Files • The general-purpose versions of I/O routines: • printf -> fprintf • scanf -> fscanf • These general-purpose functions allow us to specify the stream on which they act. • Before we can perform file I/O, we need to declare a file pointer for each physical file we want to manipulate: FILE* infile; FILE* outfile; Input and Output
File I/O I/O from Files • A file stream must be "opened" before acessing • Each call to fopen requires two arguments: • name of file to open • description of mode of operations we want to perform on that file. infile = fopen("myinfile", "r"); outfile = fopen("myoutfile", "w"); Input and Output
File I/O I/O from Files • The operation modes are: • "r" for reading • "w" for writing (an existing file will lose its contents) • "a" for appending • "r+" for reading and writing. • If the call to the fopen() function is successful, a file pointer to a logical file is returned. • Returns NULL on failed fopen() call FILE* infile; if (infile = fopen("myfile", "r") == NULL) return error; Input and Output
fprintf / fscanf fprintf and fscanf • Once a file is opened, it can be read from or written tousing fscanf() and fprintf(), respectively. • These are just like scanf() and printf(), except an additional argument specifies a file pointer. fprintf(outfile, "The answer is %d\n", x); fscanf(infile, "%s %d/%d/%d %lf", name, &bMonth, &bDay, &bYear, &gpa); Input and Output
File I/O I/O from Files #define LIMIT 1000 int main() { FILE* infile; FILE* outfile; double price[LIMIT]; int i=0; infile = fopen("myinputfile", "r"); // open for reading outfile = fopen("myoutputfile", "w"); // open for writting if ((infile != NULL) && (outfile != NULL)) { while (i < LIMIT) { if ((fscanf(infile, "%lf", &prices[i]) == EOF)) break; printf("\nprice[%d] = %10.2lf", i, price[i]); // ... process prices[i] i += 1; } } else printf("\nfopen unsuccessful!"); fclose(infile); fclose(outfile); } Input and Output
File I/O I/O from Files #include <stdio.h> void filecopy( FILE*, FILE*); int main(int argc, char** argv) { FILE* fp; if (argc == 1) filecopy(stdin, stdout); // use standard I/O else { while (--argc > 0) { if ((fp = fopen(*++argv, "r")) == NULL) { printf("\ncat: can’t open %s", *argv); return 1; } else { filecopy(fp, stdout); fclose(fp); } } } return 0; } void filecopy(FILE* ifp, FILE* ofp) { int c; while ((c = getc(ifp)) != EOF) putc(c, ofp); } Input and Output
sprintf / sscanf sprintf and sscanf • sprintf converts binary numbers to a string • int sprintf(char* buffer, const char* fmt,…); • buffer – char array big enough to hold converted number(s) • fmt – format specification • Variable list to be converted • Returns number of characters in converted string (not including null character • Useful in converting data to strings • sscanf converts a string to binary numbers • int sscanf(char* buffer, const char* fmt,…); • buffer – char array contains data to be converted • fmt – format specification • List of pointers to variables to hold converted values • Returns number of items converted • Useful to convert character data files Input and Output