140 likes | 304 Views
Chapter 22 – part c. Calls of the ...scanf functions resemble those of the ...printf functions. That similarity can be misleading, however; the ...scanf functions work quite differently from the ...printf functions. It pays to think of scanf and fscanf as
E N D
Chapter 22 – part c Calls of the ...scanf functions resemble those of the ...printf functions. That similarity can be misleading, however; the ...scanf functions work quite differently from the ...printf functions. It pays to think of scanf and fscanf as "pattern-matching" functions. The format string represents a pattern that a ...scanf function attempts to match as it reads input. If the input doesn't match the format string, the function returns as soon as it detects the mismatch; the input character that didn't match is "pushed back" to be read in the future. For example, the format string "ISBN %d-%d-%ld-%d" specifies that the input will consist of: the letters ISBN possibly some white-space characters an integer the – character an integer (possibly preceded by white-space characters) the - character a long integer (possibly preceded by white-space characters) the – character an integer (possibly preceded by white-space characters) Professor Jodi Neely-Ritz University of Florida - 2004
...scanf Conversion Specifications Conversion specifications for ...scanf functions are actually a little simpler than those for ...printf functions. A ...scanf conversion specification consists of the character % followed by the items listed below (in the order shown). • * (optional). The presence of * signifies assignment suppression: an input item is read but not assigned to a variable. Items matched using * aren't included in the count that ...scanf returns. • Maximum field width (optional). The maximum field width limits the number of characters in an input item; conversion of the item ends if this number is reached. White-space characters skipped at the beginning of a conversion don't count. • One of the letters h, 1, or L (optional). When used to read an integer, the letter h indicates that the matching argument is a pointer to a short integer; 1 indicates a pointer to a long integer. When used with e, E, f, g, or G, the letter 1 indicates that the argument is a pointer to double; L indicates a pointer to long double. Professor Jodi Neely-Ritz University of Florida - 2004
Many of the ...scanf conversion specifiers are closely related to the string conversion functions in <std.lib.Ii>, These functions convert strings (like " -297") to their equivalent numeric values (-297). The d specifier, for example, looks for an optional + or - sign, followed by a series of decimal digits; this is exactly the same form that the strtol function requires when asked to convert a string to a decimal number. Table 22.11 shows the correspondence between conversion specifiers and string conversion functions. Professor Jodi Neely-Ritz University of Florida - 2004
The examples in Table 22.12 show the effect of combining conversion specifications, white-space characters, and non-white-space characters. The examples in Table 22.13 show the effect of assignment suppression and specifying a field width. The examples in Table 22.14 illustrate the more esoteric conversion specifiers (i, [, and n). Professor Jodi Neely-Ritz University of Florida - 2004
Detecting End-of-File and Error Conditions If scanf function to read and store n data items, we expect its return value to be n. If the return value is less than n, something went wrong. • End of file. The function encountered end-of-file before matching the format string completely. • Error. An error occurred that was beyond the control of the function. • Matching failure. A data item was in the wrong format. The function might have encountered a letter while searching for the first digit of an integer. Professor Jodi Neely-Ritz University of Florida - 2004
Every stream has two indicators associated with it: an error indicator and an end-of-file indicator. These indicators are cleared when the stream is opened, and one or the other is set when an operation on the stream fails. Encountering end-of-file sets the end-of-file indicator, and an error sets the error indicator. A matching failure, however, doesn't change either indicator. Once the error or end-of-file indicator is set, it remains in that state until it's explicitly cleared, perhaps by a call of the clearerr function, clearerr clears both the end-of-file and error indicators: clearerr(fp); /* clears eof and error indicators for fp */ clearerr isn't needed often, since some of the other library functions clear one or both indicators as a side effect. We can call the feof and ferror functions to test a stream's indicators to determine why a prior operation on the stream failed. The call feof(fp) returns a nonzero value if the end-of-file indicator is set for the stream associated with fp. The call ferror(fp) returns a nonzero value if the error indicator is set. Both functions return zero otherwise. Professor Jodi Neely-Ritz University of Florida - 2004
When scanf returns a smaller-than-expected value, we can use feof and ferror to determine the problem. If feof returns a nonzero value, we've reached the end of the input file. If ferror returns a nonzero value, an error occurred during input. If neither returns a nonzero value, a matching failure must have occurred. Regardless of what the problem was, the return value of scanf tells us how many data items were read before the problem occurred. To see how feof and ferror might be used, let's write a function that searches a file for a line that begins with an integer. Here's how we intend to call the function: n = find_int("foo", &i) ; " foo" is the name of the file to be searched, i will be assigned the value of the integer, and n will be assigned the line number on which the integer was found. If a problem arises (the file can't be opened, an input error occurs, or no line begins with an integer), find_int will return an error code (-1, -2, or -3, respectively). Professor Jodi Neely-Ritz University of Florida - 2004
int find_int(const char *filename, int *ptr) { FILE *fp = fopen(filename, "r"); int line = 1; if (fp == NULL) return -1; /* can't open file */ while (fscanf(fp, "%d", ptr) != 1){ if (ferror(fp)){ fclose(fp); return -2; /* input error */ } if (feof(fp)) { fclose(fp); return -3; /* integer not found */ } fscanf(fp, “%*[^\n]") /* skip all characters up to the next new-line */ line++; { fclose(fp) ; return line; } Professor Jodi Neely-Ritz University of Florida - 2004
Character I/O – library functions that read and write single characters. Used with text streams and binary streams. Output Functions: Input Functions: putchar getchar fputc fgetc putc getc Example Program: Copying a File Line I/O – library functions that read and write lines. Used mostly with text streams. Output Functions: Input Functions: puts gets fputs fgets Professor Jodi Neely-Ritz University of Florida - 2004
Block I/O – library functions that allow a program to read and write large blocks of data in a single step: fwrite, fread fwrite – copy an array from memory to a stream fread – read the elements of an array from a stream File Positioning – every stream has an associated file position. When a file is opened the file position is set either at the beginning or the end of the file depending on the mode. fseek – changes the file position associated with the first argument (a file pointer), the second argument is a byte count and the third argument specifies whether the new position is to be calculated with respect to the beginning of the file, the current position, or the end of the file. <stdio.h> defines three macros for this purpose: SEEK_SET – beginning of file SEEK_CUR – current file position SEEK_END – end of file ftell – returns the current file position as a long integer rewind – sets the file position at the beginning fgetpos & fsetpos – working with very large files (beyond what fseek & ftell can handle) Example Program – Modifying a File of Part Records Professor Jodi Neely-Ritz University of Florida - 2004
String I/O – these functions allow us to read and write data using a string as though it were a stream. sprintf – similar to printf and fprintf except that it writes output into a character array (pointed to by its first argument) instead of a stream. sscanf – is similar to scanf and fscanf except that it reads from a string (pointed to by its first argument) instead of reading from a stream. Professor Jodi Neely-Ritz University of Florida - 2004