Download presentation
Presentation is loading. Please wait.
Published byΓερβάσιος Μαυρογένης Modified over 6 years ago
1
Files I/O, Streams, I/O Redirection, Reading with fscanf
CS 240 – Lecture 6 Files I/O, Streams, I/O Redirection, Reading with fscanf
2
Files – FILE type and fopen
Often times, it's important to read stored content off of the file system. stdio.h includes a suite of functions for the access and modification of files. To handle a file in C, one must declare a FILE pointer-type variable. FILE *inputfile; Then, you need to assign to that variable an opened file. Opening a file can be done in a number of modes: r (for read), w (for write), a (for append). There are more modes but they aren't important right now. inputfile = fopen("filename.ext", "r");
3
Files – fopen The fopen function takes two arguments, a file name and a mode. fopen(filename, mode) Modes are string values: "r" for reading; the file can be read from using fgets "w" for writing; this will delete the files contents if it already exists. "a" for appending; this will add new content to the end of a file if it already exists. If the program has permission in that folder to read/write files, the function will return a non-zero FILE* value. If the program does not have permission or there is some other error, it will return NULL, a zero value.
4
Files – Reading with fgets
Reading files is nearly identical to the way we read input. Using fgets, instead of specifying stdin, we can simple specify the FILE* for the file that we want to read from. FILE *inputfile = fopen("input.txt", "r"); if (fgets(buffer, 1000, inputfile)) /* successfully read line from file */ Effectively, reading from a file and reading from the console are treated exactly the same by the operating system. This will give us some interesting leverage later on for combining existing programs together.
5
Files – Writing with fprintf
We're familiar with printf for our outputting needs, but it's actually a wrapper over a more versatile function. fprintf(stream, formatstring, arguments…) fprintf functions just like printf except that it will output to any stream (either a file or screen). Not discussed before, but both functions return a negative on failure to output. The first argument is a stream, and the rest are the arguments to printf. Similar to fgets allowing us to specify a file or stdin, we can specify a file or stdout. FILE *outputfile = fopen("outputfile.txt", "w"); fprintf(stdout, "Hi!"); fprintf(outputfile, "Hey, %s", name);
6
Files – fflush One important thing to note about output is that your content will not be immediately sent to it's destination as you print it. This is to avoid slowdown in the operating system by programs which output one byte at a time. It's more efficient to store output temporarily in a buffer and commit output to a destination when the buffer gets full or some signal character is sent. For example, you may notice that your programs usually wait for you to hit Enter before doing anything with your input. To force the operating system to commit the output on a stream, we use fflush(stream).
7
Files – fclose When opening files, you need to be aware of the resources of the machine. Whenever you open a file for reading or writing, the OS has to mediate communication between your program and the filesystem. This is done through file descriptors, and there are a limited amount of them at any one time. When the system runs out of file descriptors, opening files will fail. When you are done with a file, you should run fclose(stream) to release the resource. On Windows, failing to fclose a file may result in the file being inaccessible by other programs until your program terminates.
8
I/O Redirection – File to Standard Input
Again, since files and console output are treated identically by the machine, we should be able to use files whenever we're expected to use written input. Without having to recompile a program to change which stream it's reading from, we can use what's called Redirection. prog arg1 arg2 <input.txt Input redirection uses the less-than (<) operator next to the file. This is done in the Linux command-line when writing a command. This is incredibly useful going forward for testing your code. Simply type out the input you expect to give manually and save it to a file.
9
I/O Redirection – Standard Output to File
It stands to reason that if you want to save the output of a program to a file, you should be able to redirect output, as well. Well, you can: prog arg1 arg2 >output.txt This will delete all the original content of output.txt if it existed. If you want to append output to the file, keeping the original content: prog arg1 arg2 >>output.txt Writing to the file uses the greater-than (>) operator Appending to the file uses the double greater-than (>>) operator.
10
I/O Redirection – Pipes, Program to Program
Often, you'll find yourself wanting to connect the output of one program to the input of another. For example, in PuTTY, you can only scroll back 200 lines of console. If you're in a folder with over 200 files, ls -l redirected into less will allow you to view all of them without cutoff. Try it. This is called piping and uses the pipe (|) operator. prog1 arg1 arg2 | prog2 argA argB The programs will actually run concurrently, stopping only if waiting for input from the previous. You can actually continue to stack pipe connections between programs indefinitely. prog1 | prog2 | prog3 | …
11
Input – Reading Numeric Values w/ fscanf
One thing to note when dealing with input is that content from file and console streams will be in raw text. Reading in a number with fgets will not grant you a numeric value! If you want to read the text representation of a number as a numeric value, you need to use fscanf. fscanf works like fprintf in reverse, it takes content from the stream and puts the values at the specified addresses. fscanf(stream, format, arguments); The arguments after the format string must be addresses. This is similar to passing a char[] as a buffer to fgets. Remember: for numeric variables, get their addresses with &varname.
12
Input – fscanf (continued)
fscanf will read one character at a time from input, matching each character against the format string. Once it reaches a placeholder (%d for example), it tries to parse the next characters in input as part of that value. If it cannot, we have a match error and fscanf stops reading input. Whitespace characters are placeholders for any number of whitespace characters. Non-whitespace characters must match up exactly or there will be a match error. The return value of fscanf is int-type and indicates the number of arguments successfully read from the stream. 0 if it reads no items and fails to match the format string. EOF or -1 if it encounters a end-of-file or a read error.
13
Input – fscanf Examples
int a; char b; fscanf(stdin, "%d %c", &a, &b); Input: "10 x" Return Value: 2 Variables: Input remaining: "" Input: "10 10" Return Value: 2 Variables: Input remaining: "0" Input: "10" Return Value: 1 Variables: Input remaining: "" int a 10 char b x int a 10 char b '1' int a 10 char b *junk*
14
Input – fscanf Examples
int a; int b; fscanf(stdin, "(%d,%d)", &a, &b); Input: "(5,6)" Return Value: 2 Variables: Input remaining: "" Input: "(5,X6)" Return Value: 1 Variables: Input remaining: "X6)" Input: "5,6)" Return Value: 0 Variables: Input remaining: "5,6)" int a 5 int b 6 int a 5 int b *junk* int a *junk* int b *junk*
15
Input – fscanf Examples
char a; int b; char c; int d; fscanf(stdin, "%c,%d", &a, &b); /* first */ fscanf(stdin, "%c,%d", &c, &d); /* second */ Input: "x,10\ny,20" First Return Value: 2 Variables: First Input remaining: "\ny,20" Second Return Value: 2 Variables: Second Input remaining: "" Input: "x 10\ny 20" First Return Value: 1 Variables: First Input remaining: " 10\ny 20" Second Return Value: 1 Variables: Second Input remaining: "0\ny 20" char a x int b 10 char c y int d 20 char a x int b *junk* char c 1 int d *junk*
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.