CHAPTER 11 ========== printf() and scanf() -------------------- - the prototype of all the standard I/O functions is in printf() returns the number of characters written, negative number on error. some conversion characters: c,d,u,o,x,e,f,g,s,p,n some formatting flags: h,l,-,0,width.precision,* scanf() returns EOF when the input stream is empty, otherwise the number of successful conversions. some conversion characters: c,d,u,o,x,e,f,g,s,p,n some formatting flags: h,l,width special conversion: *,[string],[^string] Examples -------- char c = 'A', s[] = "Blue moon!"; Format printed remarks %c "A" field width 1 by default %2c " A" field width 2, right adjusted %-3c "A " field width 3, left adjusted %s "Blue moon!" field width 10 by default %3s "Blue moon!" more space is needed %.6s "Blue m" precision 6 %-11.8s "Blue moo " precision 8, left adjusted ---------------------------------------------------------- int i = 123; double x = 0.123456789; Format printed remarks %d "123" field width 3 by default %05d "00123" padded with zeros %7o " 173" right adjusted, octal %-9x "7b " left adjusted, hexadecimal %10.5f " 0.12346" field width 10, precision 5 %-12.5e "1.23457e-01 " left adjusted, e-format ---------------------------------------------------------- int i; char c; char string[15]; scanf("%d , %*s %% %c %5s %s", &i, &c, string, &string[5]); with the following characters in the input stream: 45 , ignore_this % C read_in_this** ---------------------------------------------------------- (scanf.c) #include int main() { int n; int i; char str[4]; scanf("%d%*s%1s%n", &i, str, &n); printf("i=%d str=%s n=%d\n", i, str, n); scanf("%[^y]", str); printf("str=%s\n", str); return 0; } input: 12 xxx xx xy output: i=12 str=x n=8 str=x x ===================================================================== FILE *, fprintf(), fscanf(), sprintf(), sscanf() ------------------------------------------------ - FILE is defined in stdio.h as a particular structure with members that describe the current state of a file. Three available FILE pointers: stdin standard input file connected to the keyboard stdout standard output file connected to the screen stderr standard error file connected to the screen For text files: int fprintf(FILE *fp, const char *format, ...); int fscanf(FILE *fp, const char *format, ...); fprintf(stdout, ...); is equivalent to printf( ....); fscanf(stdin, ...); is equivalent to scanf( ....); int sprintf(char *s , const char *format, ...); int sscanf(const char *s, const char *format, ...); ===================================================================== sscanf-sprintf.c ---------------- #include int main(void) { char str1[] = "1 2 3 go", str2[100], tmp[100]; int a, b, c; sscanf(str1, "%d%d%d%s", &a, &b, &c, tmp); sprintf(str2, "%s %s %d %d %d\n", tmp, tmp, a, b, c); printf("%s", str2); } output: go go 1 2 3 ===================================================================== fopen(), fclose() ----------------- FILE *fopen(const char *filename, const char *mode); returns a pointer to the opened file or NULL if failed mode: "r" read "w" write (created if did not exist, otherwise previous contents erased) "a" append (created if did not exist, otherwise appending at end) update mode: "r+", "w+" - only FOPEN_MAX files can be open simultaneously int *fclose(FILE *fp); returns 0 on success and EOF on failure or if the file is closed ~~~~~~~~~~~~~~~~~~~~~~ fopen-fclose.c -------------- #include int main(void) { int a, sum = 0; FILE *ifp, *ofp; ifp = fopen("infile", "r"); ofp = fopen("outfile", "w"); // sum the numbers in infile and write the sum to outfile while (fscanf(ifp, "%d", &a) == 1) sum += a; fprintf(ofp, "The sum is %d. \n", sum); fclose(ifp); fclose(ofp); return(0); } ===================================================================== get and put a char ------------------ int fgetc(FILE *) gets the next character from the file returns EOF on end of file or error int getc(FILE *) macro version of fgetc() int fputc(int c, FILE *fp) writes the character c to the file returns c on success and EOF otherwise int putc(int c, FILE *fp) the macro version of fputc getchar() is equivalent to getc(stdin) putchar(c) is equivalent to putc(c, stdout) ~~~~~~~~~~~~~~~~~~~~~~ double-space.c -------------- // Double spacing a file // usage: a.out infile outfile #include #include void double_space(FILE *, FILE *); void prn_info(char *); int main(int argc, char **argv) { FILE *ifp, *ofp; if (argc != 3) { prn_info(argv[0]); exit(1); } ifp = fopen(argv[1], "r"); /* open for reading */ ofp = fopen(argv[2], "w"); /* open for writing */ double_space(ifp, ofp); fclose(ifp); fclose(ofp); return 0; } void double_space(FILE *ifp, FILE *ofp) { int c; while ((c = getc(ifp)) != EOF) { putc(c, ofp); if (c == '\n') putc('\n', ofp); /* found a newline - duplicate it */ } } void prn_info(char *pgm_name) { printf("\n%s%s%s\n\n%s%s\n\n", "Usage: ", pgm_name, " infile outfile", "The contents of infile will be double-spaced ", "and written to outfile."); } ===================================================================== Binary files: ------------- size_t fread(void *a_ptr, size_t el_size, size_t n_elem, FILE *fp); size_t fwrite(const void *a_ptr, size_t el_size, size_t n_elem, FILE *fp); both return the number of elements they succeeded to read/write fread-fwrite.c -------------- /* a simple example of using fread and fwrite * to read and write an array of structures */ #include #include #define NELEM 3 int main(void) { FILE *fp; // the product structure struct product { int cat_num; float cost; }; typedef struct product product; product productarr[NELEM] = {{2,2.1},{4,4.1},{6,6.1}}; product one_product, *product_ptr = &one_product; int i, irc; // return code fp = fopen("fread-fwrite-struct-file","w+"); assert(fp != NULL); // write the entire array into the file pointed to by fp irc = fwrite(productarr, sizeof(product), NELEM, fp); printf(" fwrite return code = %d\n", irc); // prepare for reading from the beginning of the file rewind(fp); // read from the file one product at a time for (i=0; icat_num, product_ptr->cost); } return 0; } ===================================================================== file positioning ---------------- position indicator: number of bytes from the beginning of the file, counting from 0 (also called the file's offset) void rewind(FILE *fp); - sets the file position indicator to the beginning of the file long ftell(FILE *fp); returns the current value of the file position indicator, or -1L if failed int fseek(FILE *fp, long offset, int place); sets the value of the file position indicator by offset relative to place (effects the *next* I/O operation only) returns 0 on success and non-zero otherwise place could be one of: #define SEEK_SET 0 /* beginning of the file */ #define SEEK_CUR 1 /* current position in file */ #define SEEK_END 2 /* end of the file */ ~~~~~~~~~~~~~~~~~~~~~~~~ replicate-with-caps.c --------------------- /* Replicating a file with caps */ #include #include #include FILE *gfopen(char *file_name, char *mode); // a friendly fopen() int main(int argc, char **argv) { int c; FILE *fp, *tmp_fp; if (argc != 2) { fprintf(stderr, "\n%s%s%s\n\n%s\n\n", "Usage: ", argv[0], " file_name", "The file will be doubled and some letters capitalized."); exit(1); } fp = gfopen(argv[1], "r+"); tmp_fp = tmpfile(); while ((c = getc(fp)) != EOF) putc(toupper(c), tmp_fp); rewind(tmp_fp); fprintf(fp, "---\n"); while ((c = getc(tmp_fp)) != EOF) putc(c, fp); return 0; } FILE *gfopen(char *file_name, char *mode) { FILE *fp; if ((fp = fopen(file_name, mode)) == NULL) { fprintf(stderr, "Cannot open %s - bye!\n", file_name); exit(1); } return fp; } ~~~~~~~~~~~~~~~~~~~~~~ backwards.c ----------- /* writing a file backwards */ #include #define MAXSTRING 100 int main(void) { char file_name[MAXSTRING]; int c; FILE *ifp; fprintf(stderr, "\nInput a file name: "); scanf("%s", file_name); ifp = fopen(file_name, "r"); fseek(ifp, -1, SEEK_END); /* move to the end of the file */ /* back up one character */ while (ftell(ifp) > 0) { c = getc(ifp); /* move ahead one character */ putchar(c); fseek(ifp, -2, SEEK_CUR); /* back up two characters */ } // write the first char of the file c = getc(ifp); putchar(c); putchar('\n'); return 0; } ===================================================================== additional standard I/O functions --------------------------------- int feof(FILE *fp); return non-zero when true and 0 when false line I/O: char *fgets(char *buffer, int buf_size, FILE *fp); adds '\0' after the last read character returns buffer if successful and NULL if reached the end of the file without any character read or error occurred int fputs(const char *str, FILE *fp); writes the string str to the file, without the '\0' returns non-negative value on success and EOF otherwise FILE *tmpfile(void); opens a temporary file with mode "w+", NULL if failed the file is removed after it is closed or on program exit int fflush(FILE *fp); returns 0 on success and EOF otherwise ~~~~~~~~~~~~~~~~~~~~~~