CS 241: Systems Programming Lecture 21. Binary and Formatted I/O
Fall 2019
- Prof. Stephen Checkoway
1
CS 241: Systems Programming Lecture 21. Binary and Formatted I/O - - PowerPoint PPT Presentation
CS 241: Systems Programming Lecture 21. Binary and Formatted I/O Fall 2019 Prof. Stephen Checkoway 1 Review from last time // Open and close a file. FILE *fopen( char const *path, char const *mode); int fclose( FILE *stream); // Read or
Fall 2019
1
// Open and close a file. FILE *fopen(char const *path, char const *mode); int fclose(FILE *stream); // Read or write a character. int fgetc(FILE *stream); int fputc(int ch, FILE *stream); // Read or write a string. char *fgets(char *str, int size, FILE *stream); int fputs(char const *str, FILE *stream); // Formatted output. int fprintf(FILE *stream, char const *format, ...);
2
void rewind(FILE *stream);
Actually is an alias for…
3
int fseek(FILE *stream, long offset, int whence); int fseeko(FILE *stream, off_t offset, int whence);
Reposition location in stream
4
long ftell(FILE *stream);
fseeko and ftello are specified by POSIX but not C
5
How can we get the size of a file to which we have an open FILE *stream?
fseeko(stream, 0, SEEK_END);
fseeko(stream, pos, SEEK_SET);
6
int get_file_size(char const *path, off_t *size) { FILE *fp = fopen(path, "rb"); if (!fp) return -1; int ret = -1; if (fseeko(fp, 0, SEEK_END) == 0) { if ((*size = ftello(fp)) != -1) ret = 0; } int err = errno; fclose(fp); errno = err; return ret; }
7
int get_file_size(char const *path, off_t *size) { FILE *fp = fopen(path, "rb"); if (!fp) return -1; int ret = -1; if (fseeko(fp, 0, SEEK_END) == 0) { if ((*size = ftello(fp)) != -1) ret = 0; } int err = errno; fclose(fp); errno = err; return ret; }
7
fclose() might change errno
int main(int argc, char *argv[argc]) { for (int i = 1; i < argc; ++i) {
if (get_file_size(argv[i], &size) == -1) { perror(argv[i]); } else { long long s = size; // No way to print off_t. printf("%s: %llu\n", argv[i], s); } } return 0; }
8
Don't just print arbitrary users strings printf(line); If the attacker sets the value of line they can
stack (e.g., "%x%x%x")
chars printed so far
9
int snprintf(char *str, size_t size, char const *format, ...);
string were large enough), negative on error char message[100]; snprintf(message, sizeof message, "%s %d", some_string, some_int); /* or */ size_t size = snprintf(0, 0, "%s %d", str, x); char *message = malloc(size + 1); snprintf(message, size+1, "%s %d", str, x);
10
int scanf(const char *format, ...);
11
White space matches 0 or more white space characters in the input Ordinary characters are matched against non-whitespace Conversion specifications: e.g., %8lx
12
#include <stdio.h> int main(void) { int pairs = 0; int x, y; while (scanf(" (%d ,%d )", &x, &y) == 2) ++pairs; printf("Read in %d valid pairs.\n", pairs); return 0; } Spaces in the format match white space characters, the %d skips white space so (1,2) are ( 3 , 4 ) both valid, but (0,1(2,3(4,5 gives 3 valid pairs!
13
int fscanf(FILE *stream, const char *format, ...); int sscanf(const char *str, const char *format, ...);
14
%s matches a sequence of non-whitespace characters %[chars] matches a range of characters, which can include whitespace char html_tag[32]; sscanf(line, " <%31[^>]>", html_tag);
15
Assume we have an integer variable x, how do I read in a decimal value? int x;
16
Assume we have a char array word, how do I read in a text string? char word[16];
17
fgets() / sscanf() pairing
Always does bounds checking
18
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); size_t fwrite(void const *ptr, size_t size, size_t nitems, FILE *stream);
nitems for EOF or an error
int x = 42; float y[8]; size_t num = fread(y, sizeof(float), 8, stream); num = fwrite(&x, sizeof(int), 1, stream);
19
https://checkoway.net/teaching/cs241/2019-fall/exercises/Lecture-21.html Grab a laptop and a partner and try to get as much of that done as you can!
20