EE108 Section 4 Files page 1 of 14 EM108 Software Development for Engineers Section 4 - Files 1) Introduction 2) Operations with Files 3) Opening Files 4) Input/Output Operations 5) Other Operations 6) Closing Files 7) Complex example
EE108 Section 4 Files page 2 of 14 File: Need: 4.1 Introduction A collection of data stored on the disk Input from keyboard - serious limitation - data has to be typed again each time the program is run Output to screen serious limitation - data is lost when the program ends Notes: Data access requires file reading and writing operations Data access to/from disk is slower than to/from memory Data is saved even after the program execution ends Data can be re-used File types (in C): Binary - stores data in binary format - e.g. 23 is stored as the integer 23 represented in binary: 00010111 Text (implicit) - stores data in ASCII format - e.g. 23 is stored as two characters: 2 and 3
EE108 Section 4 Files page 3 of 14 Operations: Open files: 4.2 Operations with Files fopen - opens a file Input/Output operations: fscanf - reads data from a file getc - reads a character from a file ungetc - returns a read character to the file fgets - reads a string from file fprintf - writes data to a file putc - writes a character to a file fputs - writes a string to a file Other operations fseek - sets the cursor (position) into a file feof - tests for the end of file fflush - flushes the buffer associated to a file Close file fclose - closes an opened file Notes: Any file has to be opened before input/output operations are allowed Data is stored and can be accessed only sequentially in files
EE108 Section 4 Files page 4 of 14 Definition Notes 4.3 Opening Files FILE* fopen(char* file_name, char* mode); file_name indicates the name of the file to be opened file_name can be provided relative to the current directory or could include the absolute path to the file mode indicates what operations are allowed on the file and the type of the file - operations: w - write only (in front of file) r - read only (from front of file) a - append (at the end of file) - file type: t - text (implicit) b - binary fopen associates a file descriptor to the opened file that can be used for any operations with the file fopen returns a pointer to the file descriptor Example: FILE* fp; fp = fopen(file_name, r ); fp = fopen( my_file.txt, rt ); fp = fopen( c:\\ee105\\my_file.txt, wb );
EE108 Section 4 Files page 5 of 14 4.4 Input/Output Operations Input Operations: int fscanf(file* fp, char* format, *[param]); - reads formatted data from a file - returns no of params read or EOF if end of file is encountered int getc(file* fp); - reads a character from a file and returns it int ungetc(int c, FILE* fp); - returns a read character to the file char* fgets(char* s, int n, FILE* fp); - reads a string of maximum n-1 characters from a file or until \n was encountered and adds \0 at the end - returns the string read Output Operations: int fprintf(file* fp, char* format, *[param]); - writes formatted data to a file - returns no parameters written or EOF if unsuccessful int putc(int c, FILE* fp); - writes a character to a file - returns the character written or EOF if unsuccessful int fputs(char* s, FILE* fp); - writes a string to a file - returns EOF if unsuccessful
EE108 Section 4 Files page 6 of 14 Example 1: FILE* fp; int balance; fp = fopen( my_file.txt, r ); if (fscanf(fp, %d, &balance)!= EOF) else printf( Balance is %d\n!, balance); printf( End of file encountered\n ); Example 2: FILE* fp; int balance; int ret_val; fp = fopen( my_file.txt, w ); printf( Enter balance: ) scanf( %d, &balance); ret_val = fprintf(fp, %d, balance); if (ret_val!= EOF) else printf( Balance written in file! ); printf( Error writing in file\n );
EE108 Section 4 Files page 7 of 14 Input Operations: 4.5 Other Operations int fseek(file* fp, long offset, int whence); - sets the cursor in the file indicated by fp at position offset starting from whence - whence could have the following values: SEEK_SET (=0) beginning of file SEEK_CUR (=1) current pos. in file SEEK_END (=2) end of file int feof(file* fp); - tests for the end of file in the file indicated by fp - returns a non-zero value if end of file was encountered and 0 otherwise int fflush(file* fp); - flushes the buffer associated to a file Example: FILE* fp; int balance; fp = fopen( my_file.txt, r ); if (!feof(fp)) else fscanf(fp, %d, &balance); printf( End of file encountered\n ); fflush(fp);
EE108 Section 4 Files page 8 of 14 Definition Notes 4.6 Closing Files int fclose(file* fp); fp is the pointer to the file descriptor returned by the function that opened the file frees the buffer associated to the opened file returns 0 if successful and EOF (=-1) otherwise Example: FILE* fp; int balance; float amount; fp = fopen( my_file.txt, r ); if (!feof(fp)) fscanf(fp, %d, &balance); else printf( End of file encountered\n ); fclose(fp); printf( Enter the amount: ); scanf( %f, &amount); balance = balance + amount; fp = fopen( my_file.txt, w ); fprintf(fp, %d, balance); fflush(fp); fclose(fp);
EE108 Section 4 Files page 9 of 14 4.7 Complex Example Example: A file named grades.txt stores the following information in text format: student_id grade_s1 grade_s2 The data represents student IDs and student grades for two subjects There are no more than 5000 records Read the student IDs and store them in the array studentids[], the grades for the first subject and store them in the array ee102[] and the grades for the second subject and store them in the array ee105[] Process the grades from the arrays ee102[] and ee105[], compute the average for each student and store the results in another array named avggrades[] Print on the screen the results for all the students Write data in the following format in a new file called results.txt student_id grade_s1 grade_s2 average Use four functions : read_records() compute_average() print_results() write_records()
EE108 Section 4 Files page 10 of 14 #include <stdio.h> #include <stdlib.h> /* declarations */ /* function that reads data from a file, stores it in three arrays and returns the number of records read*/ int read_records (char* file_name, int studids[], int ee102[], int ee105[]); /* function that computes the average for each student given two arrays with grades and stores the results in a third array */ void compute_average (int ee102[], int ee105[], int avg[], int size); /* function that writes data taken from four arrays into a file */ void write_records (char* file_name, int studids[], int ee102[], int ee105[], int avg[], int size); /* function that prints the studentids, grades and their average marks */ void print_results (int studids[], int ee102[], int ee105[], int avg[], int size); /* main function */ int main() { /* 1-dimensional array that stores studentids for all registered students */ int studentids[5000]; /* 1-dimensional array that stores average marks for all registered students */ int avggrades[5000];
EE108 Section 4 Files page 11 of 14 /* 1-dimensional array that stores grades for subject ee102 for all registered students */ int ee102[5000]; /* 1-dimensional array that stores grades for subject ee105 for all registered students */ int ee105[5000]; /* no current registered students (no records) */ int norecs = 0; /* welcome message */ printf( Welcome to the program!\n ); /* read records */ norecs = read_records( grades.txt, studentids, ee102, ee105); /* compute the averages */ compute_average(ee102, ee105, avggrades, norecs); /* write data to a file */ write_records( results.txt, studentids, ee102, ee105, avggrades, norecs); /* print result s */ print_results(studentids, ee102, ee105, avggrades, norecs); printf( Goodbye!\n ); } return (EXIT_SUCCESS);
EE108 Section 4 Files page 12 of 14 /* function definitions */ int read_records (char* file_name, int studids[], int ee102[], int ee105[]) { FILE* fp; int norecs = 0; char ch; /* open file */ fp = fopen(file_name, r ); while(!feof(fp)) { /* read on record from file */ fscanf(fp, %d%c%d%c%d%c, &studids[norecs], &ch, &ee102[norecs], &ch, &ee105[norecs], &ch); } /* increase the number of records read */ norecs++; /* close file */ fclose(fp); } return norecs; void compute_average (int ee102[], int ee105[], int avg[], int size) { int i; } /* parse grades and compute the average */ for (i = 0; i < size; i++) avg[i] = (ee102[i] + ee105[i])/2;
EE108 Section 4 Files page 13 of 14 void write_records (char* file_name, int studids[], int ee102[], int ee105[], int avg[], int size) { FILE* fp; int i; /* open file */ fp = fopen(file_name, w ); for (i = 0; i < size; i++) /* write a record in the file */ fprintf(fp, %d %d %d %d\n, studids[i], ee102[i], ee105[i], avg[i]); fflush(fp); } /* close file */ fclose(fp); void print_results (int studids[], int ee102[], int ee105[], int avg[], int size) { int i; printf( StudID ee102 ee105 Avg \n ); } /* parse data and print grades and average */ for (i = 0; i < size; i++) printf( %8d %3d %3d %3d \n, studids[i], ee102[i], ee105[i], avg[i]);
EE108 Section 4 Files page 14 of 14 grades.txt 60001 60 40 40200 70 70 50100 45 55 results.txt 60001 60 40 50 40200 70 70 70 50100 45 55 50 [0] [1] studentids 60001 40200... [0] [1] ee102 60 70... [0] [1] ee105 40 70... [0] [1] avggrades 50 70... [no_recs -1] 50100 [no_recs -1] 45 [no_recs -1] 55 [no_recs -1] 50 Main tasks: Read from the grades.txt file the following information for each student: StudentID, ee102 grade, ee105 grade - open grades.txt file in reading mode - read records line by line - store the data in studentids, ee102 and ee105 arrays - close the file Compute the average mark for each student using the ee102 and ee105 arrays and store the values in the avggrades array Write the following information for each student in the results.txt file: studentid, ee102 grade, ee105 grade and avg. mark - open results.txt file in writing mode - write records line by line - close the file Print on the screen the following information about each student by parsing the arrays: StudentID, ee102 grade, ee105 grade and average mark