computer programming the c languageadrianaa/teaching/acp/15_chapter 12.pdf · this is part of the...

33
This is part of the book COMPUTER PROGRAMMING THE C LANGUAGE by Adriana ALBU Conspress Publisher, Bucureşti, România, 2013 ISBN: 978-973-100-270-5

Upload: dotruc

Post on 27-Jun-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

This is part of the book

COMPUTER PROGRAMMING

THE C LANGUAGE

by Adriana ALBU

Conspress Publisher, Bucureşti, România, 2013 ISBN: 978-973-100-270-5

Chapter 12 Files

The programs created in the previous chapters are operating on data stored in RAM (Random Access Memory). This data is lost at the end of the programs.

The files are a method of storing data on disk. Thus, data is maintained and it is available even after the execution of the current program. Therefore, a file is a collection of data, it has a name and a location. The management of files is performed by the operating system.

The connection between a C program and a file is made through a stream. This stream is created once the file is opened and it is destroyed when the file is closed. Some other operations can be performed between these two actions: reading data from a file (this is an input action that brings data from disk to RAM), processing this data and writing it into the file (an output action that transfers the data from RAM back to disk).

Although there are many types of files (documents, images, databases, pro-grams), all of them are represented by two basic types associated with two streams [HS98], [CH96]:

text – sequence of characters organized by lines;

binary – sequence of 1s and 0s.

12.1 File handling The stream that represents the connection between a C program and a file uses a pointer to a new data type, FILE, which is part of the stdio.h header file. The functions that operate with files are also part of this header file. The file pointer is used by all the actions performed on the file. Its declaration is made by an instruction as: FILE *f;

12.1.1 File opening In order to access the content of a file, a program must open that file first. This action is performed by the function fopen() that creates the connection be-tween the program and the file. This function has the following prototype: FILE *fopen(const char *file_name, const char mode);

Computer Programming – The C Language

2

where:

file_name is a string containing the name of the file that is opened. If the file is not placed in the current folder, then the entire path must be specified. If the operating system that is used is based on DOS (as Microsoft Windows is) then the components of the file path are separated by backslash (“\”): C:\Documents\Programs\ex1.txt. Unfortunately, the “\” charac-ter has a special meaning within a string; the compiler will try to understand the entity that follows this character (it expects to find sequences as “\n”, “\t”). In these cases (when the file path is literally mentioned), the back-slash must be doubled: C:\\Documents\\Programs\\ex1.txt. If the path is read from the keyboard, then it is not necessary to double the character “\”;

mode defines how the file is opened. This parameter contains two compo-nents:

o the first one specifies if the file is opened for reading (r – read), writing (w – write), appending (a – append) or for a mixture of these (table 12.1.1 [HS98], [CH96], [BH92]);

o the second one is a letter that follows right after the first compo-nent and specifies if the file is opened in text mode (t) or in bi-nary mode (b). If this second component is omitted, then the file is considered of text type.

Table 12.1.1 Possible values of parameter mode

Mode Meaning

r Opens a file only for reading. The file must exist; otherwise, the function returns NULL. After the opening action, the posi-tion indicator (the file pointer) is placed at the beginning of the file.

w Opens a file only for writing. If the file doesn’t exist, it is created; if it exists, its content is overwritten (the entire content prior of opening is lost).

a Opens a file for appending. If the file doesn’t exist, it is creat-

12 – Files

3

ed; if it exists, the appending is made at the end of the file (therefore, its content is not lost). After this opening, the posi-tion indicator is placed at the end of the file.

r+ Opens a file for reading and writing. If the file doesn’t exist, the function returns NULL; if it exists, a writing without repo-sitioning the file pointer will alter the prior content of the file, because this opening places the position indicator at the begin-ning of the file.

w+ Opens a file for reading and writing. If the file doesn’t exist, it is created; if it exists, its content is overwritten.

a+ Opens a file for reading and writing. If the file doesn’t exist, it is created; if it exists, the appending is made at the end of the prior content (because the opening places the position indicator at the end of the file).

Function fopen() returns a file pointer or NULL if an error is encountered. The following sequence of code opens a text file for reading: FILE *f;

f=fopen("test.txt","r");

//actions performed on the file

Though the previous sequence doesn’t contain compilation errors, it is not a complete one. Function fopen() returns a valid pointer if it is able to open the file, but if some errors are encountered during the opening action, then the function returns NULL and no other actions can be performed on that file. For these reasons, the program must verify if the opening action succeeded. There-fore, fopen() function is usually called within a sequence of code as follows: FILE *f;

if((f=fopen("test.txt","r"))==NULL){

printf("The file cannot be opened");

getch();

return;

Computer Programming – The C Language

4

}

// actions performed on the file

This way, a message is displayed if some errors are encountered during the opening action and that area of the program is left because it is impossible to execute any actions on the file. This method will detect any error that can occur when a file is opened (e.g.: opening a file that doesn’t exist for reading, opening a read-only file for writing, creating a file within a location where the user doesn’t have the permission to write or where there is not enough free space).

12.1.2 File closing

Function fclose() is used to close a file. It has the following prototype: int fclose(FILE *f);

where f is the file pointer returned by function fopen(). The function returns 0, if the action of closing the file can be performed or EOF, in case of an error (fclose() usually fails only if there is not enough space on the disc or if the file is on a removable disk that is extracted before the closing action is fin-ished).

The files are automatically closed when the program ends its execution. Never-theless, their explicit closing is recommended for several reasons:

it ensures that all data from the temporary memory is written into the file (a reading of the file’s content without closing and reopening it may not catch the last data that is sent for writing);

it frees the file pointer, making it available for reuse; the operating systems have a limit regarding the number of files that can be simultaneously opened, therefore it could be necessary to close a file in order to open an-other one (there is a constant, FOPEN_MAX, which returns the maximum number of files that can be simultaneously opened);

if the program crashes, then the automatic closing of the files is not execut-ed; in this case the files that were not explicitly closed could remain opened, being temporary inaccessible to other programs.

The following instruction closes in a correct manner the file that was previously opened by fopen(): fclose(f);

12 – Files

5

12.1.3 File input/output actions The functions that perform the reading from a file and the writing into a file are similar to those used for reading from the keyboard and writing on the screen. The differences are that the name of the functions has the prefix “f” and that they have an extra argument: the file pointer.

Char input/output

The characters can be read and written through functions fgetc() and fputc(), respectively. These have the prototypes: int fgetc(FILE *f); int fputc(int c, FILE *f);

Function fgetc() returns the next character from the file indicated by pointer f or constant EOF (End Of File) if the end of the file is reached or if a reading error is encountered.

Function fputc() writes character c received as argument into the file indi-cated by pointer f. If an error occurs, then the function returns EOF.

Program 12.1.1 copies character by character the content of a text file (in-put.txt) into another text file (output.txt). In order to verify the read-ing, the characters are also displayed on the screen. The input file is opened for reading (r) and the output file for writing (w). Because the number of the ele-ments in a file is usually unknown, the reading is performed within a while instruction, as long as the reading function (this time fgetc()) doesn’t return EOF. When the end of the file is reached, the while is left.

Program 12.1.1 #include <stdio.h> #include <conio.h> void main(void){ FILE *fin, *fout; char c; if((fin=fopen("input.txt","r"))==NULL){

Computer Programming – The C Language

6

printf("Error: input file."); getch(); return; } if((fout=fopen("output.txt","w"))==NULL){ printf("Error: output file."); getch(); return; } while((c=fgetc(fin))!=EOF){ //file reading fputc(c, fout); //file writing putch(c); //writing on the screen } getch(); fclose(fin); fclose(fout); }

String input/output

Functions fgets() and fputs() are used to read and to write, respectively, a string from/into a file. Their prototypes are: char *fgets(char *s, int n, FILE *f); int fputs(const char *s, FILE *f);

Function fgets() reads characters from the file indicated by pointer f and stores them into string s. The reading stops when n-1 characters were read or when the end of the line is reached. If the reading stops because the end of the line was reached, meaning that the new line character was read, then this char-acter will be part of the string too. The terminator “\0” is added at the end of the string s. The function returns the string s or NULL if the position indicator is at the end of the file or if an error occurs.

Function fputs() writes string s into the file indicated by pointer f. The last written character is returned or EOF if an error occurs.

Program 12.1.2 considers an input file (courses.txt) that contains on each row the name of a discipline from the curricula, written on maximum 40 char-acters. Each discipline is read into string s and the user is asked to enter the name of the teacher, which is then concatenated to the name of the discipline. The resulted string is written into the output file (tutors.txt). The program

12 – Files

7

finishes when the end of the input file is reached and the function fgets() returns NULL.

Program 12.1.2 #include <stdio.h> #include <conio.h> #include <string.h> void main(void){ FILE *fin, *fout; char s[80],teacher[30]; if((fin=fopen("courses.txt","r"))==NULL){ printf("Error: input file."); getch(); return; } if((fout=fopen("tutors.txt","w"))==NULL){ printf("Error: output file."); getch(); return; } while((fgets(s,40,fin))!=NULL){//file reading printf("Teacher for: %s", s); gets(teacher); //keyboard reading strcat(s,teacher); strcat(s,"\n"); fputs(s, fout); //file writing } fclose(fin); fclose(fout); }

Formatted input/output

If a formatted reading or writing is needed, then functions fscanf() and fprintf() will be used. These are similar to functions scanf() and printf() that are used for the reading/writing of the standard devices (key-board and screen); for this reason they will not be detailed once again here. The

Computer Programming – The C Language

8

single difference is an extra parameter that specifies the file pointer. The proto-types of the functions that perform formatted input/output actions on a file are: int fscanf(FILE *f, const char* format [, addr,...]);

int fprintf(FILE *f, const char* format [, arg,...]);

Function fscanf() returns EOF if the end of the file is reached and function fprintf() returns EOF if a writing error occurs.

A first example of using these two functions (program 12.1.3) considers a file that contains several numbers separated by space (numbers.txt). The num-bers are read, their average is calculated and the result is displayed on the screen and it is also written into another file (result.txt). If the input file is empty, a message is displayed accordingly.

Program 12.1.3 #include <stdio.h> #include <conio.h> void main(void){ FILE *f,*g; int n, sum=0,counter=0; float average; //the input file is opened if((f=fopen("numbers.txt","r"))==NULL){ printf("Error – input file"); getch(); return; } //the numbers are read from the file while(fscanf(f,"%d",&n)!=EOF){ printf("%d ",n);//they are displayed sum=sum+n;//their sum is calculated counter++;//they are counted } if(counter==0) printf("The file is empty"); else{ average=(float)sum/counter; printf("\nThe average is: %.2f", average); //the output file is created/opened

12 – Files

9

if((g=fopen("result.txt","w"))==NULL){ printf("Error – output file"); getch(); return; } //the average is written into the result file fprintf(g,"Average: %.2f",average); } getch(); fclose(f); fclose(g); }

Program 12.1.4 is an example of both using formatted input/output functions and opening a file to append information at the end of its content. The first name and the last name of a student are read from the keyboard and then they are appended to the content of a text file (students.txt).

Program 12.1.4 #include <stdio.h> #include <conio.h> void main(void){ FILE *f; char first_name[20], last_name[20]; //opens the file for appending if((f=fopen("students.txt","a"))==NULL){ printf("Error – output file"); getch(); return; } //keyboard reading printf("The first name: "); scanf("%s", first_name); printf("The last name: "); scanf("%s", last_name); //file writing fprintf(f,"%s %s\n",first_name, last_name); printf("Data was written into the file"); getch();

Computer Programming – The C Language

10

fclose(f); }

Program 12.1.5 reads the first name and the last name of several students from the file students.txt. The user is asked to enter a mark for each student. The data of a certain student is stored in the program using a variable of type structure. All this data is then written in a formatted way into the file marks.txt: the first name on 20 characters, the last name on 20 characters also, the mark on 5 characters (two of them allocated for the decimal part); there is also one space between each two fields, therefore each line has 47 characters. Because through the formatted writing a certain number of charac-ters were allocated to each field, the file looks like a table of a database (the data seems to be written on columns): Dennis RITCHIE 10.00

Brian KERNIGHAN 9.90

Clint HICKS 9.75

Herbert SCHILDT 9.85

Program 12.1.5 #include <stdio.h> #include <conio.h> struct student{ char fname[21]; char lname[21]; float mark; }; void main(void){ FILE *in, *out; struct student s; int flag=0; if((in=fopen("students.txt","r"))==NULL){ printf("Error – input file"); getch(); return; }

12 – Files

11

if((out=fopen("marks.txt","w"))==NULL){ printf("Error – output file"); getch(); return; } //the names are read from file in //the marks are read from the keyboard //everything is written into file out while(fscanf(in,"%s%s",s.fname,s.lname)!=EOF){ printf("\n%s %s",s.fname,s.lname); printf("\nThe mark: "); scanf("%f",&s.mark); fprintf(out,"%20s %20s %5.2f\n", s.fname, s.lname, s.mark); //the flag shows that at least one row was read flag=1; } if(flag==0) printf("The file is empty"); getch(); fclose(in); fclose(out); }

12.1.4 Repositioning the file pointer When a file is opened for reading or for writing the file pointer is positioned at the beginning of that file. If the file is opened for appending, the file pointer is placed at the end of the file. The file pointer can also be located wherever with-in the file during an action that traverses it.

If random access is needed for reading or writing the content of a file, then the file pointer must be repositioned. This action is performed by function fseek() that has the prototype: int fseek(FILE *f, long offset, int whence);

where:

f is a file pointer returned by function fopen();

offset is the difference (in bytes) between the location specified by the parameter whence and the new position of the file pointer; if offset is positive, then the file pointer is moved to the right towards whence and if it is negative, then the file pointer is moved to the left;

Computer Programming – The C Language

12

whence specifies the starting point for the movement and can have one of the following three values:

o 0 (or constant SEEK_SET) – the movement is made towards the beginning of the file;

o 1 (or constant SEEK_CUR) – the movement is made towards the current position of the file pointer;

o 2 (or constant SEEK_END) – the movement is made towards the end of the file.

The function returns 0 if the file pointer is successfully moved. A non-zero value is returned if an error occurs.

Several calls of function fseek() are hereby presented. It is noticed that both the values 0, 1, 2 or the associated constants SEEK_SET, SEEK_CUR, SEEK_END can be used for argument whence.

fseek(f,7,SEEK_SET); – moves the file pointer with 7 characters to the right towards the beginning of the file.

fseek(f,0,SEEK_END); – moves the file pointer at the end of the file.

fseek(f,-10,SEEK_CUR); – moves the file pointer with 10 characters to the left of its current position.

fseek(f,7,1); – moves the file pointer with 7 characters to the right of its current position.

If a file is opened for modifying (reading and writing), then the stream that represents the connection between the C program and that file must be flushed. This action is required after an output operation; it will write any unwritten data and it is accomplished by the function fflush() with the following proto-type: int fflush(FILE *f)

where f is a file pointer returned by function fopen().

When a file is closed (at the end of a program’s execution or by fclose() calling), the stream is automatically flushed. But if this action is needed some-where else (for instance, between a writing and a reading), then fflush() is a good solution to ensure that the writing process was completed. this action doesn’t modify the position of the file pointer.

12 – Files

13

In order to illustrate through a complete program how fseek() function can be used, several data from a file is changed. The modifying is performed once the value that must be changed is read, therefore the file pointer should be moved back in order to overwrite that information.

File students.txt is considered. The features of a student (id, first_name, last_name, mark) are written in a formatted manner: the id on 5 characters, empty space, the first name on 20 characters, empty space, the last name on 20 characters, empty space and the mark on 5 characters (two of them allocated to the decimal part). Program 12.1.6 changes the mark of a student. Field id is used to uniquely identify a student. The input file looks like this: LM214 Dennis RITCHIE 10.00

LM209 Brian KERNIGHAN 9.90

LM205 Clint HICKS 9.75

LM237 Herbert SCHILDT 9.85

The id of the searched student is read within main() and then function mod-ify() is called. The file is opened with the mode r+, which allows both read-ing and writing and doesn’t remove the content of the file when this is opened. Data of each student is read (within a while instruction) and is stored into a variable of type structure. The id of the student from the file (s.id) is com-pared to the id of the searched student (specified through the argument searched received by modify() function). If these two strings are identi-cal, then the mark of this student must be changed. The new mark is read from the keyboard and the file pointer is repositioned. It must be moved back with 5 characters towards its current position; this is performed through the instruction fseek(f,-5,SEEK_CUR);. Then the new mark is written (also in a format-ter manner) over the old one. If the file is empty or the student is not found, according messages are displayed.

Program 12.1.6 #include <stdio.h> #include <conio.h> #include <string.h> struct student{ char id[6]; char first_name[21];

Computer Programming – The C Language

14

char last_name[21]; float mark; }s; void modify(char *searched){ /*the function receives as argument the id of the searched student*/ FILE *f; float new_mark; int flag=0, found=0; //the file is opened for reading and writing if((f=fopen("students.txt","r+"))==NULL){ printf("Error – the file cannot be opened"); getch(); return; } //the file is read line by line while(fscanf(f,"%s%s%s%f", s.id, s.first_name, s.last_name, &s.mark)!=EOF){ if(strcmp(s.id,searched)==0){ //if this is the searched student printf("\n%s %s %s %.2f", s.id, s.first_name, s.last_name, s.mark); printf("\nThe new mark: "); scanf("%f",&new_mark); //the file pointer is moved back fseek(f,-5,SEEK_CUR); //the mark is overwritten fprintf(f,"%5.2f", new_mark); fflush(f); found=1; //the student was found } flag=1; /*the flag shows that the file contains at least one student */ } if(flag==0) printf("The file is empty"); else if(found==0) printf("The student was not found");

12 – Files

15

getch(); fclose(f); } void main(void){ char id[6]; printf("The id of the searched student: "); scanf("%s", id); modify(id); }

12.1.5 File renaming and removing Two functions that can be used in a C program in order to rename or to remove a file are hereby presented. These functions act on a file as a whole, not only on the information it contains and they are closely related to the operating system [CH96]. It is better to let these operations be performed by the operating sys-tem; the accidental renaming or removing of certain files during the execution of the programs can create serious problems. However, sometimes it is neces-sary to create temporary files that should be removed from the disk when they become useless.

File renaming

Function rename(), which has the following prototype, should be used when the name of a file must be changed. int rename(const char *old, const char *new);

Variables old and new can contain a simple file name (in this case the file belongs to the current folder and remains there) or the entire path of the file. In the second case, the folders of the path can be different, therefore function rename() can also be used to move a file from a folder to another one.

The function returns 0 if the renaming succeeds and -1 otherwise. The errors can emerge if: the file with the old name doesn’t exist, a file with the new name already exists or the user has not enough rights to change the name or to move the file (rights to write on the new folder).

File removing

Computer Programming – The C Language

16

A file can be deleted from the disk through function remove(). This action is permanent, therefore the function should be carefully used. Its prototype is: int remove(const char *file_name);

The function returns 0 if the file was deleted and -1 if an error is encountered. The deleting can fail if: the file doesn’t exist or the user doesn’t have the rights to delete.

Program 12.1.7 uses the functions for deleting and renaming a file. A text file with features of students (id, first_name, last_name, mark) is consid-ered. The requirement is to delete a student (with the id read from the keyboard) from the file. Because a text file is not a table of a database, it is impossible to delete a record from that file; in fact it is impossible to delete anything from a text file through a C program. A trick is used in order to solve this problem: all the records of the initial file (students.txt), excepting the one that must be deleted, are copied into a temporary file (temp.txt). At the end, the initial file is removed and the temporary file receives the name of the initial file.

Program 12.1.7 #include <stdio.h> #include <conio.h> #include <string.h> struct student{ char id[6]; char first_name[21]; char last_name[21]; float mark; }s; void delete(char *searched){ /*the function receives as argument the id of the student that must be deleted*/ FILE *f,*g; int flag=0, found=0; if((f=fopen("students.txt","r"))==NULL){ printf("Error – the file cannot be opened"); getch(); return; } if((g=fopen("temp.txt","w"))==NULL){

12 – Files

17

printf("Error – the file cannot be created"); getch(); return; } //the features of each student are read while(fscanf(f,"%s%s%s%f", s.id, s.first_name, s.last_name, &s.mark)!=EOF){ if(strcmp(s.id,searched)==0){ printf("\n%s %s %s %.2f",s.id, s.first_name, s.last_name, s.mark); found=1; } else /*if this is not the searched student, its features are written into the temporary file*/ fprintf(g,"%5s %20s %20s %5.2f\n", s.id, s.first_name, s.last_name, s.mark); flag=1; } if(flag==0) printf("The file is empty"); else if(found==0) printf("The student was not found"); getch(); fclose(f); fclose(g); //the initial file is removed remove("students.txt"); /*the temporary file is renamed with the name of the initial file*/ rename("temp.txt", "students.txt"); } void main(void){ char id[6]; printf("The id of the searched student: "); scanf("%s", id); delete(id); }

Computer Programming – The C Language

18

12.2 A complete example Program 12.2.1 gathers in an extensive application some of the previous exam-ples and also adds other functionalities. Several actions performed on a table of a database are simulated; the table is represented by a text file. It contains for-matted data about students (id, fname, lname, group, mark). This data is handled within the program through a structure with five members (struct student). The program provides a menu where the user can find the follow-ing options (figure 12.2.1):

1 – Adds a student to the file (figure 12.2.2); 2 – Lists the content of the file (figure 12.2.3); 3 – Displays the students with scholarship – those with the average mark greater than a certain value (fig-ure 12.2.4); 4 – Displays the students that belong to a certain group (figure 12.2.5); 5 – Searches a student using its id (figure 12.2.6); 6 – Modifies the information about a student (fig-ure 12.2.7);

7 – Deletes a student (figure 12.2.8); 0 – Ends the program.

Apart from the option of ending the program (which is performed by a simple call of function exit()), separated functions were implemented for all the other options. These functions, together with the user interfaces associated to each option, are hereby presented.

The file is opened in mode a when a student is added. The user is asked to enter all information about that student; these are written into the file through function fprintf(). The writing is per-formed in a formatted manner, so as the file pre-serves a tabular form (the id on 5 characters, the first name on 20 characters, the last name also on 20

characters, the group on a single char and the average mark on 5 characters, two of them for the decimal part; there is a space between each two of this five fields). The field that is used to identify a student is the id (it is supposed that it’s impossible to have more than one student with a certain id).

Figure 12.2.1 Menu

Figure 12.2.2 Add

12 – Files

19

In order to see the entire information from the file, it is opened in mode r. The file is traversed line by line, until its end (EOF). Variable flag is used to identify the case when the file is empty. It has the initial value 0; if at least one line is read from the file, the flag receives the value 1. At the end of the

function this variable is checked and if it still has the value 0, then this means that the file is empty and the user is notified through a message about this situa-tion.

The third option displays the students that have the average mark greater than or equal to a value specified by the user (sch_mark). The file is opened (r), it is traversed line by line and the average mark of each student (s.mark) is compared to the value

that is required to obtain scholarship. Variable flag is used here, too, in order to point out that the file is empty. Another variable, found, is used to deter-mine if there is at least one student with scholarship. If at the end of the func-tion variable found still has its initial value 0, this means that no students with the required mark were found.

If the user chooses the forth option, he/she is asked to specify a group; all the students that belong to that group are displayed. The file is opened in mode r and it is traversed line by line. The stu-dents that have their group (s.group) identical to the one specified by the user

(group) are displayed. In order to identify the cases when the file is empty or a certain group doesn’t exist, variables flag and found are used here, too.

Figure 12.2.3 List

Figure 12.2.4 Students with scholarship

Figure 12.2.5 Students of a group

Computer Programming – The C Language

20

A student is searched using an id specified by the user. It is consid-

ered that it’s impossible to have more than one student with a certain id, there-fore any student can be identified. Function strcmp() is used because the id is a string. Variables flag and found point out that the file is empty or that the student was not found.

The user has the possibility to change the group and/or the average mark of a student that is identi-fied through his id in a process similar to the one from the

searching function. This time the file is opened for reading and writing (r+). If the student is found, his old data is displayed. The user enters (if he/she wants) new values for the group (s.group) and/or for the average mark (s.mark). The file pointer is moved back with 7 characters (1 for group, a space and 5 for mark) and the new data overwrites the old information. Variables flag and found are set in order to notify if the file is empty or if the student doesn’t exist in the file.

In order to delete a student (together with all his infor-mation) from a file, the student must be identified using his id (the process is similar to the one used by the searching

function). The file is opened for reading. A temporary file is created, and opened for writing; it will store all students, except for the one that should be deleted. In order to notify the user whether the file is empty or the student doesn’t exist, this function uses variables flag and found too. At the end of the function the initial file is removed and the temporary file is renamed, receiv-ing the name of the initial file.

Function main() only displays the menu (in a repetitive manner) and, accord-ing to the user’s option, executes one of the implemented functions. The entire program is hereby presented.

Figure 12.2.6 Search

Figure 12.2.7 Modify

Figure 12.2.8 Delete

12 – Files

21

Program 12.2.1 #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> struct student{ char id[6]; char fname[21]; char lname[21]; int group; float mark; }; int menu(void){ int option; printf("1-Add\n"); printf("2-List\n"); printf("3-Scholarship\n"); printf("4-Group\n"); printf("5-Search\n"); printf("6-Modify\n"); printf("7-Delete\n"); printf("0-Exit\n"); printf("Your option: "); scanf("%d",&option); return option; } void add(void){ FILE *f; struct student s; if((f=fopen("students.txt","a"))==NULL){ printf("Error - file cannot be opened"); getch(); return; } printf("Id: "); scanf("%s", s.id);

Computer Programming – The C Language

22

printf("First name: "); scanf("%s", s.fname); printf("Last name: "); scanf("%s", s.lname); printf("Group: "); scanf("%d", &s.group); printf("Average mark: "); scanf("%f", &s.mark); fprintf(f,"%5s %20s %20s %1d %5.2f\n", s.id, s.fname, s.lname, s.group, s.mark); fclose(f); } void list(void){ FILE *f; struct student s; int flag=0; if((f=fopen("students.txt","r"))==NULL){ printf("Error - file cannot be opened"); getch(); return; } while(fscanf(f,"%s%s%s%d%f", s.id, s.fname, s.lname, &s.group, &s.mark)!=EOF){ printf("%s %s %s %d %.2f\n", s.id, s.fname, s.lname, s.group, s.mark); flag=1; } if(flag==0) printf("Empty file"); fclose(f); getch(); } void scholarship(void){ FILE *f; struct student s; int flag=0, found=0; float sch_mark; if((f=fopen("students.txt","r"))==NULL){ printf("Error - file cannot by opened"); getch(); return; } printf("Mark for scholarship: ");

12 – Files

23

scanf("%f", &sch_mark); while(fscanf(f,"%s%s%s%d%f", s.id, s.fname, s.lname, &s.group, &s.mark)!=EOF){ if(s.mark>=sch_mark){ printf("%s %s %s %d %.2f\n", s.id, s.fname, s.lname, s.group, s.mark); found=1; } flag=1; } if(flag==0) printf("Empty file"); else if(found==0) printf("No students with scholarship"); fclose(f); getch(); } void gr(void){ FILE *f; struct student s; int flag=0, found=0; int group; if((f=fopen("students.txt","r"))==NULL){ printf("Error - file cannot be opened"); getch(); return; } printf("Group: "); scanf("%d", &group); while(fscanf(f,"%s%s%s%d%f", s.id, s.fname, s.lname, &s.group, &s.mark)!=EOF){ if(s.group==group){ printf("%s %s %s %d %.2f\n", s.id, s.fname, s.lname, s.group, s.mark); found=1; } flag=1; } if(flag==0) printf("Empty file"); else if(found==0)

Computer Programming – The C Language

24

printf("The group doen's exist"); fclose(f); getch(); } void search(void){ FILE *f; struct student s; int flag=0, found=0; char searched[6]; if((f=fopen("students.txt","r"))==NULL){ printf("Eroare - deschidere fisier"); getch(); return; } printf("Id of the searched student: "); scanf("%s", searched); while(fscanf(f,"%s%s%s%d%f", s.id, s.fname, s.lname, &s.group, &s.mark)!=EOF){ if(strcmp(s.id, searched)==0){ printf("%s %s %s %d %.2f", s.id, s.fname, s.lname, s.group, s.mark); found=1; } flag=1; } if(flag==0) printf("Empty file"); else if(found==0) printf("The student doesn't exist"); fclose(f); getch(); } void modify(void){ FILE *f; struct student s; int flag=0, found=0; char searched[6]; char answer; if((f=fopen("students.txt","r+"))==NULL){

12 – Files

25

printf("Error - file cannot be opened"); getch(); return; } printf("Id of the searched student: "); scanf("%s", searched); while(fscanf(f,"%s%s%s%d%f", s.id, s.fname, s.lname, &s.group, &s.mark)!=EOF){ if(strcmp(s.id, searched)==0){ printf("%s %s %s %d %.2f\n", s.id, s.fname, s.lname, s.group, s.mark); found=1; printf("Do you modify the group (Y/N)?"); answer=getch(); if(toupper(answer)=='Y'){ printf("\nNew group: "); scanf("%d",&s.group); } printf("Do you modify the average mark (Y/N)?"); answer=getch(); if(toupper(answer)=='Y'){ printf("\nNew average mark: "); scanf("%f",&s.mark); } fseek(f,-7,SEEK_CUR); fprintf(f,"%1d %5.2f",s.group,s.mark); fflush(f); } flag=1; } if(flag==0) printf("Empty file"); else if(found==0) printf("The student doesn't exist"); fclose(f); getch(); } void del(void){ FILE *f, *g; struct student s;

Computer Programming – The C Language

26

int flag=0, found=0; char searched[6]; if((f=fopen("students.txt","r"))==NULL){ printf("Error - file cannot be opened"); getch(); return; } if((g=fopen("temp.txt","w"))==NULL){ printf("Error - file cannot be opened"); getch(); return; } printf("Id of the searched student: "); scanf("%s", searched); while(fscanf(f,"%s%s%s%d%f", s.id, s.fname, s.lname, &s.group, &s.mark)!=EOF){ if(strcmp(s.id, searched)==0){ printf("This record will be deleted:\n"); printf("%s %s %s %d %.2f", s.id, s.fname, s.lname, s.group, s.mark); found=1; } else fprintf(g,"%s %s %s %d %.2f\n", s.id, s.fname, s.lname, s.group, s.mark); flag=1; } if(flag==0) printf("Empty file"); else if(found==0) printf("The student doesn't exist"); remove("students.txt"); rename("temp.txt","students.txt"); fclose(f); fclose(g); getch(); } void main(void){ int o; while(1){

12 – Files

27

o=menu(); switch(o){ case 1: add(); break; case 2: list(); break; case 3: scholarship(); break; case 4: gr(); break; case 5: search(); break; case 6: modify(); break; case 7: del(); break; case 0: exit(0); default: printf("Wrong option!"); getch(); } } }

12.3 Questions and exercises A. Find the error.

1. int x=7; fprintf("%d", x);

2. int x=7; fprintf("aFile.txt", "%d", x);

3. FILE *f; int x=7; f=fopen("aFile.txt","r"); fprintf(f, "%d",x);

4. FILE *f; int x=7; f=fopen("aFile.txt","w"); fprintf(f,"%d",x); f=fclose();

5. FILE *f; int x; f=fopen("aFile.txt","w+"); fscanf(f,"%d",&x);

6. FILE *f; int x;

Computer Programming – The C Language

28

f=fopen("aFile.txt","r+"); fscanf(f,"%d",&x); fseek(f,SEEK_CUR,-5); fprintf(f, "%d",++x);

B. Considering the following programs, specify what will be printed on the screen once these programs are executed.

7. #include <stdio.h> void main(void){ FILE *f; float a=1.234, b=5.678, x; f=fopen("aFile.txt","w+"); fprintf(f,"%6.2f %6.2f",a,b); fseek(f,-13,SEEK_CUR); fscanf(f,"%f",&x); printf("%.3f",x); fclose(f); }

8. #include <stdio.h> void main(void){ FILE *f; char word[20]="File"; f=fopen("aFile.txt","w"); fprintf(f,"Programming"); fclose(f); f=fopen("aFile.txt","w+"); fscanf(f,"%s",word); printf("%s",word); fclose(f); }

9. #include <stdio.h> void main(void){ FILE *f; char word[20]="File"; f=fopen("aFile.txt","a+"); fprintf(f,"Programming"); fscanf(f,"%s",word); printf("%s",word);

12 – Files

29

fclose(f); }

C. Choose the correct answer (one only).

10. How many arguments does function fopen() have?

□ a) 0; □ b) 1; □ c) 2; □ d) 3; □ e) the number of arguments is undefined.

11. Which should be the value of mode argument of function fopen() if a text file must be opened for reading?

□ a) "r"; □ b) "w"; □ c) "a"; □ d) "r+"; □ e) "r-".

12. Function fopen() returns:

□ a) a structure; □ b) constant EOF if the end of the file is reached; □ c) the name of the file; □ d) the content of the file; □ e) a pointer of type FILE.

13. Which function should be used to print in a formatted manner an argu-ment into a file?

□ a) fscanf(); □ b) fprintf(); □ c) printf(); □ d) fgets(); □ e) all answers are wrong.

14. Which of the following letters cannot be used within mode argument of function fopen()?

□ a) a; □ b) b; □ c) c; □ d) r; □ e) w.

15. Once fscanf() function reaches the end of a file, it returns:

□ a) EOF; □ b) NULL; □ c) SOS; □ d) nothing; □ e) all answers are wrong.

16. Argument whence of function fseek() can have the value:

□ a) SEEK_SET; □ b) SEEK_CUR; □ c) SEEK_END; □ d) the answers a, b and c are correct; □ e) all answers are wrong.

17. The argument of function fclose() is:

□ a) the name of the file (including the path, if necessary); □ b) the file pointer returned by function fopen(); □ c) the content of the file; □ d) function fclose() doesn’t have arguments; □ e) all answers are wrong.

18. The type of a file pointer is:

Computer Programming – The C Language

30

□ a) file_pointer; □ b) NULL; □ c) FILE; □ d) EOF; □ e) file.

D. Write programs to solve the following problems.

19. Text file numbers.txt contains real numbers separated by space. Find out how many numbers the file contains, which are the minimum and the maximum; store these three elements into another file, re-sult.txt.

20. Several words, separated by space, are stored into file words.txt. Find out and display the longest word.

21. File employee.txt contains the name and the age of the employees of a company. Calculate the average age in that company.

22. Text file phonebook.txt contains information (name, address, phone number, etc.) about the clients of a telephone company. Dis-play the phone number of a person whose name is read from the key-board.

23. File accounts.txt contains information about bank accounts (ac-count_number, owner, sum, and currency). The program allows the deposit or the withdrawal from an account identified by its number. If a withdrawal is requested, it must be verified if the account contains the required sum.

24. Create a program that acts on a text file with information about the products from a store (id, name, features, quantity, and price). The program should allow, through a repetitive menu, the fol-lowing actions:

a. add a product – the user is responsible to enter unique values for the id, which is the field that identifies a product;

b. list the products – all data about a product is displayed;

c. display the total value of the products from the store;

d. search a product by its id – the result is, at most, one product, because the id is unique;

e. search a product by its name – all products that have the speci-fied name are displayed (for instance, it is possible to have two products with the name “bread”, but with different features: one could be “rice bread, 500g” and the other “corn bread, 300g”);

12 – Files

31

f. display the cheapest product – the user enters a name; the mini-mum is only searched for that category (for instance, if the user enters bread, the cheapest bread is displayed);

g. display the products that need supply – products with the quanti-ty zero;

h. modify the price and/or the quantity of a product – the product is identified by id;

i. delete a product identified by id;

j. exit.

12.4 Answers to questions and exercises

A. 1. The first argument of function printf(), which should be the file pointer, is missing. 2. The functions that act on the content of a file (as printf() does) receive as argument the file pointer returned by function fopen() when the file is opened, not the name of the file. 3. The file is opened for reading (mode r), but a writing is attempted (fprintf()). 4. Function fclose() should receive as argument the file pointer f, not to return it. 5. The sequence of code doesn’t generate a compilation error, but the reading (fscanf()) is useless if it is performed right after the file is opened. Even the mode w+ allows both reading and writing, the content of the file is deleted by the opening process, therefore fscanf() doesn’t have anything to read at that moment and it returns EOF. 6. The last two parameters of fseek() function are not correctly placed; the first one of them is the offset (-5) and then the whence (SEEK_CUR).

B. 7. Numbers a and b are written into the file on 6 characters, but with only 2 decimals (therefore the values from the file are 1.23 and 5.68). There is also a space between the two values. Function fseek() moves back the file point-er with 13 characters, right where the first number was written; therefore, this number is read by fscanf(). Though the printing on the screen is made with 3 decimals, the number read from the file has only two decimals; for this rea-son, 1.230 is displayed on the screen. 8. The file is opened in mode w, the word "Programming" is written and the file is closed. Then the reading of the written word is attempted, but the file is reopened in mode w+, which means that its content is erased. Therefore, function fscanf() has nothing to read and returns EOF, without changing variable word; "File" is displayed on the

Computer Programming – The C Language

32

screen. 9. The file is opened in mode a+, which allows both appending and reading. Once function fprintf() adds the text "Programming", the file pointer is positioned at the end of the file, therefore function fscanf(), that follows, doesn’t have anything to read and variable word maintains its value "File", which is displayed.

C. 10. c) – function fopen() has two arguments: the name of the file and the opening mode. 11. a). 12. e). 13. b). 14. c). 15. a). 16. d). 17. b). 18. c).