Mastering File Input and Output in C: Streams and Error Handling
This tutorial covers the essentials of managing file input and output in C programming. Learn how to utilize pointers and the FILE data structure to control file streams, perform error handling, and effectively open, read, write, and close files. We delve into different file modes (e.g., read, write, append) and illustrate how to use functions like fopen(), fclose(), and fscanf() to read and write data. Gain insights on reading multiple fields from files and ensuring your programs handle potential errors gracefully.
Mastering File Input and Output in C: Streams and Error Handling
E N D
Presentation Transcript
C Programming – Part 6 File Input and Output TEC 284
Streams • In C we use pointers to manage streams that read and write data • Streams are just file or hardware devices such as a monitor or pointer which can be controlled by a C program • We use pointers to the stream in order to control them • To point to and manage a file stream in C, an internal data structure called FILE is used
FILE #include <stdio.h> main () { //create 3 file pointers FILE *pRead; FILE *pWrite; FILE *pAppend; } • Each FILE pointer can essentially open and manage a separate file
Opening and Closing Files • When working with files, the basic steps involve opening the file, processing the file and then closing the file • After opening the file, there should always be some error checking/handling to ensure the file was successfully opened before working on the file • The fopen() function is used • fopen() returns a FILE pointer when the file is successfully opened
Opening a file in C main () { FILE *pRead; pRead = fopen(“file1.txt”,“r”); } • fopen() takes two arguments • The name of the file to be opened • A flag to indicate how the file should be opened • In this example, the file file1.txt is opened in read-only mode
Text file open modes • r - read text mode • w - write text mode (truncates file to zero length or creates new file) • a - append text mode for writing (opens or creates file and sets file pointer to the end-of-file) • r+ - read and write text mode • w+ - read and write text mode (truncates file to zero length or creates new file) • a+ - read and write text mode (opens or creates file and sets file pointer to the end-of-file
fopen() results • If the file does not exist and it is opened with read mode (r), then the open fails. • If the file is opened with append mode (a), then all write operations occur at the end of the file regardless of the current file position. • On success a pointer to the file stream is returned. On failure a null pointer is returned
Opening a file in C with error handling main () { FILE *pRead; pRead = fopen(“file1.txt”,“r”); if(pRead == NULL) { printf(“\nFile could not be opened”); } else { printf(“\nFile was opened for reading”); } }
Check for NULL if(pRead == NULL) Can be shortened to if(pRead) • If pRead returns a non-NULL, the if condition is true. • If pRead returns NULL, the condition is false
Closing a file • After opening and processing a file, the file should be closed using fclose() • fclose() uses the FILE pointer to flush the stream and close the file • This frees up memory resources for the CPU and is good programming practice • fclose() takes a pointer to a file as its argument • fclose(pRead);
Reading a file • For simplicity, the test file the example is referring to is just a text file containing names Names.txt John Michael Frank Stacy Robert
Reading a file main () { FILE *pRead; char name[20]; pRead = fopen(“Names.txt”,“r”); if(pRead == NULL) { printf(“\nFile could not be opened”); } else { printf(“\nContents of file:\n”); fscanf(pRead, “%s”, name); while(!feof(pRead)) { //feof() checks for end-of-file //feof() returns a non-zero value when the end-of-file //marker is reached printf(“%s\n”,name); fscanf(pRead, “%s”, name); } fclose(pRead); } }
Results of the program Contents of file : John Michael Frank Stacy Robert
Reading multiple fields • fscanf() can read multiple fields by supplying a series of type specifiers for the second argument • E.g. fscanf(pRead, “%s%s”, name, hobby); • The %s specifier will read a series of characters until a white space is found, including a blank, new line or tab
Reading multiple fields test file Hobbies.txt Michael Programming Sheila Shopping Spencer Football Olivia Dancing
Code to read multiple fields main () { FILE *pRead; char name[20], char hobby[15]; pRead = fopen(“Hobbies.txt”,“r”); if(pRead == NULL) { printf(“\nFile could not be opened”); } else { printf(“\nName\tHobby\n\n”); fscanf(pRead, “%s%s”, name, hobby); while(!feof(pRead)) { //feof() checks for end-of-file //feof() returns a non-zero value when the end-of-file //marker is reached printf(“%s\t%s\n”,name, hobby); fscanf(pRead, “%s%s”, name, hobby); } fclose(pRead); } }
Results Name Hobby Michael Programming Sheila Shopping Spencer Football Olivia Dancing
Writing Data • Similarly to how printf() is used to send information to the screen fprintf() can be used to send information to a file • fprintf() uses a FILE pointer to write data to a file • The fprintf() function takes a FILE pointer, a list of data types and a list of values (or variables) to write the information to a file
Writing to a file main () { FILE *pWrite; char fName[20], char lName[20], char id[15], float gpa; pWrite = fopen(“Students.txt”,“w”); if(pRead == NULL) { printf(“\nFile could not be opened”); } else { printf(“\nEnter first name, last name, id and GPA\n”); printf(“Enter data separated by spaces: ”); //store data entered by the user into variables scanf( “%s%s%s%f”, fName, lName,id, &gpa ); //write variable contents separated by tabs fprintf(pWrite, “%s\t%s\t%s\t%.2f\n”,fName, lName, id, gpa); fclose(pWrite); } //end if }
Reading the same record back main () { FILE *pRead; char fName[20], char lName[20], char id[15], float gpa; pRead = fopen(“Students.txt”,“r”); if(pRead == NULL) { printf(“\nFile could not be opened”); } else { //print heading printf(“\nName\t\tID\t GPA\n\n”); //read field info from file and store in variables fscanf( “pRead”, “%s%s%s%f”, fName, lName,id, &gpa ); //print variable data to standard output printf(“%s %s\t%s\t%.2f\n”,fName, lName, id, gpa); fclose(pRead); } //end if }
Appending to a file • When opening a file using fopen() with a w argument value will erase any previous data stored in the file • Use the a attribute to append data at the end of the file • If the file does not exist, a new one will be created
Appending code example //This program appends to our previous Hobbies.txt file example main () { FILE *pWrite; char name[20], char hobby[20]; pWrite = fopen(“Hobbies.txt”,“a”); if(pRead == NULL) { printf(“\nFile could not be opened”); } else { printf(“\nEnter a new name and hobby: ”); //store data entered by the user into variables scanf( “%s%s”, name, hobby); //write variable contents separated by tabs fprintf(pWrite, “%s\t%s\n”,name, hobby); fclose(pWrite); } //end if }