Security-Oriented C Tutorial 0x15 - File I/O
Hello readers, in this tutorial, we will be discussing how to perform file operations such as reading and writing.
There are two methods of accessing files: file descriptors and file streams. We will be learning about file streams because it is a higher level form of the file descriptor and allows a more power to the programmer and is more portable.
Although a "file" can refer to something that can be things such as a socket, the screen or the keyboard, we will only look at its uses with the more common file on disk.
To declare a file pointer variable, we first use the FILE type followed by the asterisk (*) and the name just like any other pointer. Easy.
To open a file for reading using the fopen function, we are required to specify the file name and a mode to say how it should be opened. In this example, we are using the r mode for reading where the file should already exist. In practice, we must always check the return value of fopen to see if it has successfully executed or not. fopen returns NULL into our file pointer if it has failed.
Next we retrieve the contents of the file with the fgets function, passing in the buffer to hold the contents, the size of the buffer and the file pointer. fgets reads from fp until it reaches an EOF or a newline. In our file, we do not have a new line character so it will reach an EOF. An EOF (end-of-file) character symbolizes the end of a file.
Once we have read from the file, we can use printf to display the string inside buf and then proceed to close the stream. If we do not close the stream, it may have leaks.
Now that we've covered reading, let's try doing a write.
This time we use the w mode for fopen using the file name meaning that a file will be opened for writing. The w mode will create the file if it does not already exist, else it will erase the contents of the existing file and start anew.
Using the fprintf function, we print the contents of buf into the file through the file stream fp kind of like using printf to print into the console output. Let's see the results.
And remember to close the stream!
Before compiling and running, we check if our file exists and it looks like it doesn't. After compiling and running, we can clearly see it now does exist and using the cat tool, we can see its contents and it seems like our program did exactly what we intended.
Of course, there are more modes than just r and w. Here is a table, from the University of Leicester's Dr. Richard Mobbs' Introduction to C, summarizing them.
Nothing to it, just needs the usual practice and experimentation to get the feel of the procedure to declare, open and do the read/write, then closing the stream when you are finished.