C: Advanced Topics-II Summer 2014 COMP 2130 Intro Computer Systems Computing Science Thompson Rivers University File Handling a. There are different types of files: Unformatted Files a. b. Text Files Formatted Files a. b. TRU-COMP2130 Text Files with fprintf and fscanf Binary Files C: Advanced Topics 2 Text Files We have discussed the text files (even with command line arguments) The steps are: Open a file Write or read Close the file TRU-COMP3710 Introduction 3 Formatted files The files created with fprintf, can be read using fscanf in the same sequence The steps are again the same Open/create the file Read/write on the file (using fscanf/fprintf) Close the file TRU-COMP3710 Introduction 4 Binary Files Binary files are very similar to arrays of structures, except the structures are in a disk-file rather than an array in memory. There are two features, that distinguish binary files from text files: You can instantly use any structure in the file. You can change the contents of a structure anywhere in the file. The steps are: Create/open the file Write/read the structure Close the file TRU-COMP3710 Introduction 5 Operations on Binary File Open the file with “b” in the mode After opening, one can read and write a structure on the file It is also possible to seek a specific position in the file. The position is at record 0 when the file is opened. A read operation reads the structure where the file position indicator is pointing to. After reading the structure the pointer is moved to point at the next structure. A write operation will write to the currently pointed-to structure. After the write operation the file position indicator is moved to point at the next structure. The fseek function will move the file position indicator to the record that is requested. The ftell returns the current value of the file pointer TRU-COMP3710 Introduction 6 Common File Access operations #include <stdio.h> FILE *in, *out; // FILE is defined in <stdio.h> in = fopen(“in_filename”, “r”); // mode: r, w, a, r+, w+, a+ if (in == NULL) ... out = fopen(“out_filename”, “w”); fclose(in); fprintf(out, “format ...”, variables...); fscanf(...); fgets(...); TRU-COMP2130 C: Advanced Topics 7 Opening and using binary files The opening modes may be: TRU-COMP3710 Introduction 8 Special binary file operations int fseek(FILE*, long, SEEK_SET or SEEK_CURRENT or SEEK_END); // move file position pointer int fwrite(void*, int memb_size, int no_memb, FILE*); int fread(void*, int memb_size, int no_memb, FILE*); int ftell ( FILE * stream ); TRU-COMP3710 Introduction 9 Defining the structure The record or the structure is defined as: struct member { int mem_id; char mem_name[25]; int salary; }; * We may use typedef to define the user defined datatype as well TRU-COMP3710 Introduction 10 To create the file and add records void create() { fp=fopen("Binary.txt", "ab"); struct member m; int ans=1; while (ans==1) { printf("\nEnter Member ID : "); scanf("%d", &m.mem_id); printf("\nEnter Member Name : "); scanf("%s",m.mem_name); printf("\nEnter Salary : "); scanf("%d", &m.salary); fwrite(&m, sizeof(struct member),1,fp); // this is writing the address of the structure on the file printf("\n\nPress '1' to add more and '0' to go back : "); scanf("%d", &ans); if (ans==0) {fclose(fp); return;} if (ans!=0 && ans !=1) printf("Invalid option entered "); } fclose(fp); } TRU-COMP3710 Introduction 11 Reading all the records void display() { fp=fopen("Binary.txt", "rb"); struct member mem; int a; while(1) { fread(&mem, sizeof(struct member), 1, fp); // read a specific record at the record pointer if (feof(fp)) break; printf("\nMemebr ID : %d\nMember Name : %s\nSalary : %d\n", mem.mem_id, mem.mem_name, mem.salary); } printf("Press '0' to go back "); scanf("%d", &a); fclose(fp); } TRU-COMP3710 Introduction 12 Reading a specific record In order to read a specific record, the number of record is taken from the user and then fseek is used to move the record pointer void search() { int a; struct member mem; fp=fopen("Binary.txt", "rb"); while(1) { printf("Enter the record number to search : "); scanf("%d", &a); fseek(fp, sizeof(struct member)*(a-1), 0); // seeking the location from the beginning of the file fread(&mem, sizeof(struct member),1, fp); printf("\nMemebr ID : %d\nMember Name : %s\nSalary : %d\n", mem.mem_id, mem.mem_name, mem.salary); printf("Press '1' to search more and '0' to go back : "); scanf("%d", &a); if (a==0) {fclose(fp); return;} if (a!=0 && a!=1) printf("Invalid input "); } } TRU-COMP3710 Introduction 13 Fseek() The fseek may be used to travel anywhere in the file: int fseek ( FILE * stream, long int offset, int origin ); The origin may be: Offset would be negative with SEEK_END TRU-COMP3710 Introduction 14 Rewind() This positions the record pointer to the beginning of the file void rewind ( FILE * stream ); TRU-COMP3710 Introduction 15 Update a record First the record is read and it may also be written back with the new values void update() { int a; fp=fopen("Binary.txt", "r+"); //this would open in read as well as write mode char name_temp[25]; int sal_temp; struct member mem; while(1) { printf("Enter the record number to search : "); scanf("%d", &a); fseek(fp, sizeof(struct member)*(a-1), 0); //this is searching the specific record fread(&mem, sizeof(struct member),1, fp); printf("\n\nEnter new name : "); scanf("%s", mem.mem_name); //inputting the new name and salary printf("\n\nEnter new salary : "); scanf("%d", &mem.salary); fseek(fp, -sizeof(struct member), SEEK_CUR); //we need to go back to the original position to write back fwrite(&mem,sizeof(struct member), 1, fp); printf("\n\n Record Updated "); } TRU-COMP3710 Introduction 16 Display the record After reading the record, the simple display is: printf("\nMemebr ID : %d\nMember Name : %s\nSalary : %d\n", mem.mem_id, mem.mem_name, mem.salary); If we wish to define a function to display the members values: showOne(&mem); It is passing the address and pointer would receive the value TRU-COMP3710 Introduction 17 Using pointer values void showOne(struct member *ptr) { printf("\nMember ID : %d", ptr->mem_id); //we use -> in spite of . printf("\nMember Name : %s", ptr->mem_name); printf("\nSalary : %d\n\n", ptr->salary); } TRU-COMP3710 Introduction 18 void print_rcd(struct student_rcd rcd) { printf(“Number: %d\n”, rcd.student_number); printf(“Name: %s\n”, rcd.name); // name is an array. // not &(rcd.name) } void read_rcd(struct student_rcd *rcd) { printf(“Enter number: “); scanf(“%d”, &(rcd->student_number)); // reference rqd printf(“Enter name: “); scanf(“%s”, rcd->name); // name is an array. // not &(rcd->name) } TRU-COMP2130 C: Advanced Topics 19 Delete a record Once created, we may edit the data, but cannot delete Read all records and transfer to other file except the one’s you wish to delete Rename the new file while (1) { fread(&mem,sizeof(struct member),1,fp); //reading from fp if (feof(fp)) break; if (strcmp(naam, mem.mem_name) == 0) { printf("A record with requested name found and deleted.\n\n"); found=1; } else { fwrite(&mem, sizeof(struct member), 1, fp_tmp); //writing on fp_tmp } } remove("Binary.txt"); rename("tmp.bin", "Binary.txt"); TRU-COMP3710 Introduction 20 Some extra methods: void menu() //to show all the menu options { system("clear"); printf("\n\n\t\tM A I N M E N U \n"); printf("\t1. Create the Binary File \n"); printf("\t2. Display the contents of the file \n"); printf("\t3. Seek a specific record \n"); printf("\t4. Update the contents of a record \n"); printf("\t5. Delete a record for the specific name \n"); printf("\t6. Exit \n"); } int input() //to take user input {int a; printf("\n\t\tPlease Enter your choice .... "); scanf("%d", &a); return(a); } TRU-COMP3710 Introduction 21 Screen shots TRU-COMP3710 Introduction 22 Formatted files To create a file void create() { fp=fopen("format.txt", "a"); int mem_id; char mem_name[25]; int salary; int ans=1; while (ans==1) { printf("\nEnter Member ID : "); scanf("%d", &mem_id); printf("\nEnter Member Name : "); scanf("%s",mem_name); printf("\nEnter Salary : "); scanf("%d", &salary); fprintf(fp, "%d %s %d\n",mem_id, mem_name, salary); printf("\n\nPress '1' to add more and '0' to go back : "); scanf("%d", &ans); if (ans==0) {fclose(fp); return;} if (ans!=0 && ans !=1) printf("Invalid option entered "); } fclose(fp); } TRU-COMP3710 Introduction 23 Read To read the file void display() { fp=fopen("format.txt", "r"); int mem_id; char mem_name[25]; int salary; int a; while(!feof(fp)) { fscanf(fp, "%d %s %d\n", &mem_id, mem_name, &salary); printf("\n\t Member ID : %d \n\tMember Name : %s \n\tSalary : %d\n", mem_id, mem_name, salary); } printf("Press '0' to go back "); scanf("%d", &a); fclose(fp); } TRU-COMP3710 Introduction 24 Search a member_id while(1) { found=0; printf("Enter the record number to search : "); scanf("%d", &a); rewind(fp); while(!feof(fp)) { fscanf(fp, "%d %s %d\n", &mem_id, mem_name, &salary); if (mem_id==a) { found=1; printf("\nMemebr ID : %d\nMember Name : %s\nSalary : %d\n", mem_id,mem_name, salary); } } if (!found) printf("This Member_ID is not present "); printf("Press '1' to search more and '0' to go back : "); scanf("%d", &a); if (a==0) {fclose(fp); return;} if (a!=0 && a!=1) printf("Invalid input "); } TRU-COMP3710 Introduction 25