Echo The File
In this example, we will read the contents of a the file line by line and print its content to the screen. We will assume that each line of the file contains no more than 1000 characters.
Opening Files for Reading.
Similar to performing output to a file, if we want to read information out of a file, we need to create a handle to the file. The main difference between this and the previous example is the mode we are opening the file with. As we wish to read from the file, we will open the file in read mode by supplying "r" for the mode.
Basic syntax is as follows
FILE* variableName = fopen(filename, "r");
Remember that just like when we open the file for writing, we need to check our file pointer to ensure that we were successful in reading the file. For example, if we typo the name of the file, the fopen() function could be unsuccessful if there is no file with the provided name. This would result in the fopen() function returning NULL.
Read a Line using fgets()
The fgets() function reads an entire line from a file up to a given number of characters. This limit must be supplied. The function returns NULL if the end of file character (EOF) is encountered before reading any other data. We can use this to check if we have reached the end of the file.
//here we declare a variable to hold one line of our file
char line[1001];
int rc;
//read the line from the file, this function call will only read 1000 chacters at most
//the last character is reserved for '\0' character
//if the read was successful, rc will not be NULL. if it was successful, rc will be NULL
rc = fgets(line, 1001, fp);
fgets() includes the newline character (\n) in the string if one is present.
Putting it together
Suppose I wanted to read the lines out of a file named "sampleinput.txt". This is one way that this could be done using fgets()
#include <stdio.h>
int main(void)
{
//this variable holds one line from our file. Used for reading our files
char line[1001];
//pointer to a file opened for reading
FILE* fp = fopen("sampleinput.txt", "r");
//test if file was successfully opened
if(fp != NULL){
while(fgets(line, 1000, fp) != NULL){
printf("%s", line);
}
}
fclose(fp);
return 0;
}
fgets() is good for reading in one line of the file at a time and then working with the entire line of input as a string.
Read a Line using fscanf()
Another method for reading our line out involve using fscanf(). fscanf() is similar to scanf() but you read from a file instead. When you read with fscanf() you need to provide the function with a matching format code to read what you want. We cannot use %s because %s reads only a single token. If we had a line like this:
this is a line in the file
%s would only allow us to read this. The space would stop the reading of the rest of the line.
To get around this problem, we can use regular expressions
regular expressions is a powerful tool used to match/search/manipulate text information. It is something that is widely used in computing and we would not have time to discuss all of this in details. However, we will demonstrate the use of some of the most common ones that we could use.
In our example, we want to read out an entire line of a file. A line in the file ends with a newline character. Thus, we can handle this by using a regular expression in our format code to match a piece of text that includes everything except newlines. a format code that involves regular expressions uses [] to hold the regular expression.
This is what we would use to read a line of text that includes every character except the newline. The format code for this is:
%[^\n]
This format code means we are expecting a string and to essentially treat everything other than a newline.
fscanf() returns the number of values correctly read. if an fscanf() expression was successful, its return value would be equal to the number of of format codes in its format string.
Putting all this together, here is an alternative version of our echo program that uses fscanf() instead of fgets()
#include <stdio.h>
int main(void)
{
//this variable holds one line from our file. Used for reading our files
char line[1001];
//pointer to a file opened for reading
FILE* fp = fopen("sampleinput.txt", "r");
//test if file was successfully opened
if(fp != NULL){
//one format code below, %[^\n]. This matches any string up to but not including
//a newline. The \n after the format code is there to "read out" the new line so
//that we can move on to reading the next line
while(fscanf("%[^\n]\n") == 1){
//note the difference in how we must print here.. previously we printed
//with just %s. This is because the newline was added to string using fgets().
//However, fscanf() does not store the newline when the format code excludes it.
//thus we need to write one ourselves at the end of the line
printf("%s\n", line);
}
}
fclose(fp);
return 0;
}