Assignment 6 – Direct Access File Manipulation
60-141 – Introduction to Programming II
Direct Access File Manipulation:
In this assignment you are asked to develop a C program that will input character data sequentially from a text file, convert the input to machine compatible formats for storage within a structure, store the structures as binary records in a direct access file and then perform a sort of the direct access file records before producing a formatted output to stdout. In addition, you will determine the total number of bytes containing in the input file and in the direct access file and output those values for comparison. You should note that character (i.e. text) files typically require much more storage than binary files due to the fact that binary files store data in the actual machine format, or representation, of various data types.
Steps:
1. In order to test your program, prepare a text file for input – you should call it assign6.dat. The input file must consist of at least 10 lines of data. Each line begins with a 6 digit ID that must be unique, as well as 10 arbitrary float values from 0.0 to 100.0. Each value must be separated from the following value by at least one space character, except the last one which is followed by the end-of-line. This file represents a set of student grades for each student in 10 courses (assume the same courses for all students).
The following steps all pertain to the C program you must write.
2. Declare and initialize all variables, data structures and file structures you will need for this program. You will need a structure with members for storing the unique ID (int), the 10 course marks (array of float), and the GPA (float).You will also need variables to count the number of bytes in the input text file and output binary file.
3. For each input text file record, input the entire string – use either gets() or fscanf(). Once the string has been inputted you can determine its length using strlen(). You will need to extract each of the data fields to populate (i.e. transfer data to) the structure members for the ID and marks – you might want to use sscanf() for this task. At this time you can calculate the GPA and store it in the structure.
4. Once you have populated a structure, you should then output the structure to a binary file called assign6out.dat. Determine the size of the structure, in bytes, using the sizeof pre-processor operator, and add this to the total count of bytes used in the binary file. If there is no more data in the input file you should continue to the next step, but if more data exists then you must repeat steps 3 and 4. You must not use an array to input all data; instead, you must process each input record separately before proceeding to the next.
5. With all of the data outputted to the binary file, you must now perform a sorting operation on the
records, so that after the sort is finished, all the records in the binary file are sorted in ascending order
by ID. Note that to perform this sort you will likely need at least 2 different structures to read in binary
records to do the comparison needed, and then restore the records in required order. You may use any
sort algorithm but a selection sort might be simplest. For this part, you must not use any other files –
your sort must be in place (i.e. within the binary file itself).
6. The final output from your program must consist of the sorted records of student marks, including their
GPA, on one output line for each record. Following this, you must output the total number of bytes
inputted to the program from file assign6.dat, as well as the total number of bytes required to store all
data in structures stored in the binary file assign6out.dat. Direct your final output to the file
assign6results.dat.
Requirements:
– Write and document a complete C program that is capable of satisfying the requirements of this
assignment problem.
Answer:
/* Title: Assignment #6: Direct Access File Manipulation Objective: This program will input character data sequentially from a text file, convert the input to machine compatible formats for storage within a structure */ #include<stdio.h> #include<string.h> #define MAX 130 //creat a structure studInfo typedef struct { int ID; float marks[10]; float GPA; }studInfo; /*Prototypes*/ long int textSizeFile(FILE *); studInfo analyze(char [MAX]); void display(const studInfo *); void print(studInfo); int main() { FILE *p; char line[MAX]; int a; studInfo var; /*open the file assign6.dat for reading*/ p = fopen("assign6.dat", "r+"); long int textSize = textSizeFile(p); printf("Size of the file = %ld\n", textSize); long int bSize = 0; for(a = 0; a < 10; a++) { /*Read the line*/ fscanf(p, "%127[^\n]", line); /*Read characters*/ fgetc(p); var = analyze(line); display(&var); bSize += sizeof(studInfo); } /*Display the size of the binary file */ printf("The Size of binary file = %ld\n", bSize); /*Open the binary file assign6out.dat to read*/ FILE *readPtr = fopen("assign6out.dat", "rb"); /*Create a temp structure*/ studInfo temp; /*Display the content on the screen*/ puts("Before Sorting"); for(a = 0; a < 10; a++) { fread(&temp, sizeof(studInfo), 1, readPtr); /*Display the content on the screen*/ print(temp); } /*Set the pointer back to the beginning of the file*/ rewind(readPtr); /*Sort the binary file */ studInfo data, data2; /*To write to the file assign6results.dat*/ FILE *writePtr = fopen("assign6results.dat", "w"); int check = 1; while(check) { check = 0; fread(&data, sizeof(studInfo), 1, readPtr); /*A loop to check all the file*/ while(fread(&data2, sizeof(studInfo), 1, readPtr) != '0') { if(data.ID > data2.ID) { /*Back 2 bytes*/ fseek(readPtr, sizeof(studInfo) * -2, SEEK_CUR); fwrite(&data2, sizeof(studInfo), 1, readPtr); fwrite(&data, sizeof(studInfo), 1, readPtr); check = 1; } else { /*Next record*/ data = data2; } } if(check) { /*Set the pointer back to the beginning of the file*/ rewind(readPtr); } } /*Display the content on the screen after sorting*/ puts("After Sorting"); for(a = 0; a < 10; a++) { fread(&temp, sizeof(studInfo), 1, readPtr); print(temp); } /*close all open files*/ fclose(p); fclose(readPtr); fclose(writePtr); return 0; } /* Objective: Print content to the file Input:structure data Output: Return size */ void print(studInfo data) { printf("%d %.1f %.1f\n", data.ID, data.marks[0], data.GPA); } long int textSizeFile(FILE *p) { long int size; fseek(p, 0, SEEK_END); size = ftell(p); fseek(p, 0, SEEK_SET); return size; } /* Objective: analyze the content to the file Input:An array s Output: return data */ studInfo analyze(char s[MAX]) { studInfo data; sscanf(s, "%d %f %f %f %f %f %f %f %f %f %f", &data.ID, &data.marks[0], &data.marks[1], &data.marks[2], &data.marks[3], &data.marks[4], &data.marks[5], &data.marks[6], &data.marks[7], &data.marks[8], &data.marks[9]); int total = 0, a; for(a = 0; a < 10; a++) { total += data.marks[a]; } data.GPA = total/10; return data; } /* Objective: Print content to the file Input:a pointer to the structure Output: Print content to the file */ void display(const studInfo *var) { FILE *bPtr = fopen("assign6out.dat", "ab"); fwrite(var, 1, sizeof(studInfo), bPtr); fclose(bPtr); }
Leave a reply