[go: up one dir, main page]

0% found this document useful (0 votes)
9 views24 pages

1.6 - Review FileIO

The document provides a comprehensive guide on File Input/Output (I/O) in C programming, detailing how to create file pointers, check file existence, open files in various modes, and read/write data using functions like fgetc, fgets, fscanf, and fprintf. It includes examples demonstrating the use of these functions for reading from and writing to files, as well as handling errors and closing file pointers. Additionally, it covers advanced topics such as searching within files using rewind and fseek functions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views24 pages

1.6 - Review FileIO

The document provides a comprehensive guide on File Input/Output (I/O) in C programming, detailing how to create file pointers, check file existence, open files in various modes, and read/write data using functions like fgetc, fgets, fscanf, and fprintf. It includes examples demonstrating the use of these functions for reading from and writing to files, as well as handling errors and closing file pointers. Additionally, it covers advanced topics such as searching within files using rewind and fseek functions.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

File Input/Output (I/O) in C

Dr. Tanvir Ahmed


Contents
• File I/O intro
• How to create a file pointer
• How should we check the file exist or not
• Different modes of opening a file
• Reading from an input file
• Closing a file pointer
• Example: fgetc and fputc
• Example: fgets
• Example: fscanf and fprintf
• Example: reading file and string the data in arrays to process the data
• List of important functions
• rewind() and Search operation.
• fseek
• Example: searching in a file and updating the file with the help fo
fseek
File I/O intro
• So far we have entered information into our
programs via the computer's keyboard.

• Although this works fine for small sets of input, this


would be very time consuming for processing large
amounts of data.

• Furthermore, large amounts of data often already


exist in text files. It would certainly be wasteful to
type these data in by hand while running a program
when they are already available in a file.
File I/O Intro
• C provides the ability to read from files, (AND write to files.)
• In fact, when we read information from the keyboard and wrote
information to the screen, we primarily used the functions
• printf
• scanf
• Similarly, for reading from files and writing to files, we'll use the
functions
• fprintf
• fscanf
• The first f in each of these function calls stands for "file."
• Here is the specification for each function:
• fprintf(file_ptr, ctrl_str, other_arguments)
• fscanf(file_ptr, ctrl_str, other_arguments)
• You'll notice that these are identical to printf and scanf EXCEPT for
the first parameter.
How to Create a File Pointer
• In order to read from a file, or write to a file, you MUST use a pointer to that
file.
• Here is a declaration of a file pointer:
• FILE *fp;

• This file pointer is not pointing to any file yet.


• In order to properly "initialize" a file pointer, it must be set to point to a file.
• In order to do this, we must specify the following:
• 1) Name of the file
• 2) Mode ("r" for read or "w" for write)
• There is a function call that uses this information to open the appropriate file
and return a pointer to it.
• It's name is fopen.
• Here is an example of its use:
• fp = fopen("input.txt", "r");
• This line look for input.txt file in the same directory where the code is running,
and the open the file in read mode. The file pointer is pointing to the beginning of
the file
How to Create a File Pointer
• Here is an example of fopen:
• fp = fopen("input.txt", "r");
• You'll notice that the first parameter to the fopen function is a string storing
the name of the file to be opened.
• The second parameter is also a string. For our purposes, this string will either
be "r" or "w " or some other options we will see later.
• When we open a file in "r" (reading) mode,
• the file should already exist and the fopen function returns a pointer to the
beginning of that file.
• If the file doesn't exist, fopen returns NULL.

• Some important note:


• To read the input.txt file, you should keep the file in same directory where your
code is running
• It will not search in your full computer or other folder if you just write input.txt
• If you want your code to run files from another folder, you have to provide the
path of the file instead of just writing “input.txt”
• For example:
• fopen(“c:/documents/input.txt", "r");
We should check whether we found the file
or not
The following piece of code can be used to see whether your program
managed to open the file or not:

FILE *fp;
if ((fp = fopen("myfile.c", "r")) ==NULL)
{
printf("Error opening file\n");
exit(1);
}
• The different values for mode are as follows:
Value Description
•r Open a file for reading.
•w Create a file for writing.//if you have a file with same name, it
will replace the file.
•a Append to a file.
• r+ Open a file for read/write. The file must exist
• w+ Create a file for read/write. opens a text file in both reading and
writing mode. If the file exists, it's truncated first before overwriting. Any
old data will be lost. If the file doesn't exist, a new file will be created.
• a+ Append or create a file for read/write. // file is created if does
not exist
• There are many other modes available
How to Read from an Input File
• After opening file in read mode, you can use various functions to
read the information from the file
• ch=fgetc(fp);
• fgetc() reads the character from current pointer position, advances
the pointer position so that it now points to the next character and
returns the character that is read which we collect to the variable ch.

• Once the file is opened, we refer the file through the file pointer fp.
• How long should you keep reading?
• Until you reach to the end of the file
• How do I know I am at the end?
• EOF will help you to notice that.
• Closing a File:

• fclose( ) closes the stream, writes any data remaining in the disk buffer
to the file, does a formal operating system level close on the file, and
frees the associated file control block.
fclose( ) has this prototype:
int fclose(FILE *fp);
• A return value of zero signifies a successful operation.
Example with fgetc(): reads a char from a file
#include <stdio.h>
#include <stdlib.h> • This code reads a text file with
name in.txt, prints all the
int main(void) {
FILE *ifp, *ofp;
information in the file in the
char ch; console and also to a new file
ifp = fopen("in.txt","r"); //open file in read mode out.txt
ofp = fopen("out.txt","w"); //open file in read mode
if(ifp==NULL || ofp == NULL) //if cannot open file • Before running this code, you
{
printf("Cannot open file \n");
should keep a text file with some
exit(1); data/text in it and place it in the
} same folder of your code
while(!feof(ifp)) //loop until ifp reaches to EOF • As you are reading character by
{
ch = fgetc(ifp); //read a char and move ifp forward
character, you can process them:
• May be count words, count characters,
if (ch!=EOF) count vowels
{
• Also, store them in char arrays.
printf("%c", ch);

}
fputc(ch, ofp);//put a char and move ofp forward • In this code, feof() checks whether
you reached to the EOF or not.
}
fclose(ifp); //close the ifp • PS: repl.it sometimes does not
fclose(ofp);//close the ofp work well for file I/O. You can
return 0;
practice it in your computer using
} code blocks or other IDE, if needed
Example with fgets(): reads a line from a file
#include <stdio.h> • Prototype of fgets() function:
#include <stdlib.h>
• char *fgets(char *str, int n, FILE
int main(void) { *stream)
FILE *ifp;
char str[100]; • Parameters
ifp = fopen("in.txt","r"); • str − This is the pointer to an array of
if(ifp==NULL) //if cannot open file
{ chars where the string read is stored.
printf("Cannot open file \n");
exit(1);
• n − This is the maximum number of
//return 0; characters to be read (including the
} final null-character). Usually, the length
of the array passed as str is used.
while( fgets (str, 100, ifp)!=NULL )
{ • stream − This is the pointer to a FILE
str[strcspn(str, "\n")] = ‘\0’; //remove ‘\n’ from str object that identifies the stream where
puts(str); //print str
characters are read from.
} • Note that fgets() will also keep the ‘\n’
fclose(ifp); //close the file
in your string str.
}
return 0;
• To remove that ‘\n’ from your string,
you can use the foollwing line:
• str[strcspn(str, "\n")] = 0;
fscanf and fprintf
• Like scanf and printf for console, we can use fscanf and fprintf for
taking data from file and putting data into a file.
• Your input file needs to be properly formatted to read using fscanf.
• For example, if you want to read an integer using fscanf, your input
file also should contain integer at a specific part of the file.
• Let us consider the following content of a students.txt file
5
861022 Adam 65 72 56
851102 Allan 78 45 80
860501 Smith 55 75 90
841205 Ahmed 75 80 95
850630 Puja 40 50 48
• The first integer in the file says, how many students information are
available in the file.
• Next, 5 lines contain the student information of 5 students. One
student for each line. It includes, student id number, student last
name, and scores for 3 Courses. All data are separated by space.
fscanf and fprintf
• Content of a students.txt file
5
861022 Adam 65 72 56
851102 Allan 78 45 80
860501 Smith 55 75 90
841205 Ahmed 75 80 95
850630 Puja 40 50 48
• Now, we will write a program that reads the students.txt file and
produce out.txt file with the student id, student last name, and
average grade for the students from the three grade provided in the
students.txt file.
fscanf and fprintf Students.txt
5
#include <stdio.h>
int main () { 861022 Adam 65 72 56
851102 Allan 78 45 80
FILE * infile;
FILE * outfile; 860501 Smith 55 75 90
int student_ID, j,g1,g2,g3, n; 841205 Ahmed 75 80 95
char student_name[30];
float avg; 850630 Puja 40 50 48
infile = fopen("students.txt", "r" ); //read mode
outfile = fopen("students_avg.txt" , "w");//write mode
fscanf(infile, "%d",&n); //read the first integer

for (j =1; j <= n; j++) { //loop n number of times to read n students


fscanf( infile, "%d", &student_ID); //read student id
fscanf( infile, "%s", student_name); //read last name
fscanf( infile," %d %d %d ", &g1, &g2, &g3); //read 3 grades
avg = (g1+g2+g3)/3.0;
printf("%d %s %d %d %d %.2f\n", student_ID, student_name, g1, g2,g3,
avg);
fprintf(outfile,"%d %s %.2f\n", student_ID, student_name, avg);
}
fclose(infile); //close infile
fclose(outfile); //close outfile. Data will not be written if you do not close

return 0;
}
Modifying student_grade code
• Now, if we want to print the student who got highest grade or
if we want to store them in an array, how would you
approach?
• We will also add another integer in the input file’s first line
that represents number course grade per students.
Students.txt
• We have three different types of data 53
• Integer, string, and float 861022 Adam 65.5 72 56
• There are 3 float numbers per student (if three courses) 851102 Allan 78 45.5 80

• So, we will declare: 860501 Smith 55 75 90


841205 Ahmed 75 80 95
• An integer array: int ids[MAX_SIZE]
850630 Puja 40 50 48
• An array of strings: char Lnames[MAX_SIZE][20]
• A 2D array of float: float grades[MAX_SIZE][COURSE_SIZE]
• How would we track the students across three arrays?
• The index 0 for all the array will be for first student
• Next index will be for second student, etc.
#include <stdio.h> // we have all the data in our arrays now!
#define MAX_SIZE 100 float max_avg = -1.0;
#define MAX_COURSES 10 int max_index=0;
int main () { for (i =0; i < n ; i++) {
FILE * infile; if (avgs[i]>max_avg){
FILE * outfile; max_avg = avgs[i];
int ids[MAX_SIZE], n, courses, i, j; max_index = i;
char LNames[MAX_SIZE][20]; }
float grades[MAX_SIZE][MAX_COURSES]; }
float avgs[MAX_SIZE];
infile = fopen("students2.txt", "r" ); fprintf(outfile, "============\nStudent
outfile = fopen("students_avg2.txt" , "w"); with highest average score: \n");
fscanf(infile, "%d",&n); fprintf(outfile,"%d %s %.2f\n",
fscanf(infile, "%d",&courses); ids[max_index], LNames[max_index],
fprintf(outfile, "List of students avgs[max_index]);
data\n==========\n"); fclose(infile); // Close both files.
float total; fclose(outfile);
for (i =0; i < n ; i++) {
total = 0.0; printf("Please see the students_avg.txt
fscanf( infile, "%d", &ids[i]); file for result");
fscanf( infile, "%s", LNames[i]); return 0;
for(j=0; j<courses; j++) { //get courses }
number of grades for student i
fscanf( infile," %f", &grades[i][j]); Students.txt
total += grades[i][j]; 53
}
861022 Adam 65 72 56
avgs[i] = total/courses; 851102 Allan 78 45 80

fprintf(outfile,"%d %s %.2f\n", ids[i], 860501 Smith 55 75 90


LNames[i], avgs[i]); 841205 Ahmed 75 80 95
}
850630 Puja 40 50 48
Function Description
fopen()> Opens a file.
fclose()> Closes a file.
fputc()> Writes a character.
fgetc()> Reads a character.
Is to a file what printf()
fprintf()>
is to the console.
Is to a file what scanf()
fscanf()>
is to a console.
Example of using rewind and menu based search
• When you perform a single search in a file, the file pointer
moves forward and maybe it can reach to the end of the file if
the item you are looking for does not exist.
• If you want to perform a search operation in a file one after
another, then you need to move the file pointer to the
beginning after every search operation.
• rewind() is a function that can move the file pointer to the
beginning. You just need to pass file pointer to this function.
• See the example in the next slide!
• For the example we will consider the following file data:
861022 Adam 65 72 56
851102 Allan 78 45 80
860501 Smith 55 75 90
841205 Ahmed 85 70 95
850630 Puja 40 50 48
int main ()
{
FILE * infile;
int id, n, courses, i, j, g1, g2, g3;
char LName[20]; rewinding before every search
char search_key[20], new_name[20];
infile = fopen("students4.txt", "r" );
char ch;
while(1){
printf("Menu:\n1. Search by Name\n2. any other key to exit: ");
ch = getchar();
if(ch == '1')
{
rewind(infile); // moves the file pointer to the beginning
char search_key[20];
printf("Enter a name to search: ");
scanf("%s", search_key);
printf("Looking for %s\n", search_key);
int found = 0;
while(fscanf( infile, "%d %s %d %d %d", &id, LName, &g1, &g2, &g3) != EOF)
{
if(strcmp(search_key, LName)==0) {
found = 1;
printf("We found %s in our record\n", search_key);
printf("ID: %d, Name: %s Grades: %d %d %d\n", id,LName,g1,g2, g3);
break;
}
}

The code continues to the next slide


if(!found)
printf("Sorry could not find the name\n");

}
else //if the your pressed other key
{
printf("Thanks for using our search system\n");
break;
}
char cleanup;

while((cleanup=getchar() != '\n') && cleanup != EOF); // flushing


the ‘\n’ pressed when entering the last name to keep the code
taking input

}
return 0;
}
Use of fseek and editing file
• If you have observed all of our file I/O codes so far just
sequentially read the file.
• We read/write from/to the file based on exact position of the file pointer at a
particular moment
• Whenever you read something from the file, the file pointer moves forward
• fseek is a function that can be used to move the cursor to
different places of your file
• Here is the prototype:
• int fseek(FILE *pointer, long int offset, int position)
• pointer: pointer to a FILE object that identifies the stream.
• offset: number of bytes to offset from position (can be negative too)
• position: position from where offset is added.
• returns: zero if successful, or else it returns a non-zero value
• position defines the point with respect to which the file pointer needs
to be moved by offset. It has three values:
SEEK_END : It denotes end of the file.
SEEK_SET : It denotes starting of the file.
SEEK_CUR : It denotes file pointer’s current position.
Example of using fseek() to edit our file
• Now, we will write a code where we will open a file in
r+ mode
• So we will be able to both read and write using same pointer
• We will use the same file we used in our last examples
• We will ask the user to provide a name to search and to provide a modified
name so that we can update our file

• Strategy:
• We will start reading the file from the beginning as we did in our earlier
examples
• When we read a name, we will compare it with the search key and if matches
• We will move the file pointer backwards by the length of the search key so that we can
replace it!
• Let’s see the code in the next slide
#define MAX_SIZE 100
//remaining part of the code from the left side
#define MAX_COURSES 10
if(i==n)
int main () {
printf("Name does not exist.");
FILE * infile;
fclose(infile); // Close both files.
int id, n, courses, i, j;
char LName[20];
printf("File updated if found.");
float grades[MAX_COURSES];
return 0;
char search_key[20], new_name[20];
}
infile = fopen("students3.txt", "r+" );
fscanf(infile, "%d",&n);
fscanf(infile, "%d",&courses);
printf("Enter a name to edit and the new name: "); fseek moves the cursor to the
scanf("%s %s", search_key, new_name); beginning of the name found
printf("Finding the student...\n");
//subtract string length from
for (i =0; i < n ; i++) {
fscanf( infile, "%d", &id); the current position of the
fscanf( infile, "%s", LName); pointer
if(strcmp(search_key, LName)==0)
{ After moving the pointer,
printf("Found the name. Updating..."); write the new_name to
fseek(infile, -strlen(LName), SEEK_CUR); replace it.
fprintf(infile, "%s",new_name); They can be in different
break;
}
lenght
for(j=0; j<courses; j++) {
fscanf( infile," %f", &grades[j]);
}
However, this code has a problem as if the new name length is not exact same as the name you are replacing, then it will keep
} older char or replace some grades with the new string if it is longer. There are various logic to deal with that. Maybe you can
keep/load the full data in your code and write a new temp file, remove the old file and rename the temp file to the original file
name. You can use remove, rename functions. But we leave it up to here and you can explore further. Use this logic as the
starting point.

You might also like