Let us suppose that we have a structure Person with the following attributes:
-Name (string) (the string can contain spaces)
-Age (integer)
-Salary (real)
-Email (string) (cannot contain spaces)
We shall consider a simple program that writes into a text file a struct vector of the Person type and then loads from the same text file the data into a new struct vector of the Person type.
#include<stdio.h> #include<string.h> /*The size of the buffer used for reading from the text file*/ #define BUFFER_SIZE 250 /*The maximum size of the name field in the Person struct*/ #define MAX_NAME_SIZE 80 /*The maximum size of the email field in the Person struct*/ #define MAX_EMAIL_SIZE 60 /*The maximum number of persons*/ #define MAX_PERSONS 10 /*The relative path to the file where you can find the text file*/ #define PATH_TO_TXT_FILE "persons.txt" /*The character who will be used to replace the space character*/ #define SPACE_REPLACEMENT '$' typedef struct { char name[MAX_NAME_SIZE]; int age; double salary; char email[MAX_EMAIL_SIZE]; }Person; /* * Description: * Replaces all occurrences of @replacedChar with @replacementChar * Parameters: * string - the string where the replacement process will take place * replacedChar - the character who will be replaced * replacementChar - the character who will replace the @replacedChar * Returns: * Nothing */ void ReplaceChar(char* string, char replacedChar, char replacementChar) { int size = strlen(string); int i; for(i=0; i<size;i++) { if(string[i]==replacedChar) { string[i] = replacementChar; } } } /* * Description: * Outputs to stdout the content of the Person vector * Parameters: * p - a pointer to the the Person vector * numberOfPersons - how many elements the vector has * Returns: * Nothing */ void Persons_Print(Person *p, int numberOfPersons) { int i; for(i = 0; i<numberOfPersons; i++) { printf("%s %d %f %s\n",p[i].name,p[i].age,p[i].salary,p[i].email); } } /* * Description: * Saves in the text file represented by @stream the content of the * person vector. * Parameters: * p - a pointer to the Person vector * numberOfPersons - how many elements the vector has * stream - a pointer to the text file */ void Persons_Save(Person *p, int numberOfPersons, FILE* stream) { int i; for(i = 0; i<numberOfPersons; i++) { /*Replaces all spaces in the name string in order to be able to load a person's name */ ReplaceChar(p[i].name,' ',SPACE_REPLACEMENT); /*Writes the structure into the text file*/ fprintf(stream, "%s %d %f %s\n",p[i].name,p[i].age, p[i].salary,p[i].email); /*Brings the name string back to normal*/ ReplaceChar(p[i].name,SPACE_REPLACEMENT,' '); } } /* * Description: * Loads in the Person vector the contents of the text file * Parameters: * p - a pointer to the Person vector * numberOfPersons - how many elements the vector has * stream - a pointer to the text file * Returns: * Nothing */ void Persons_Load(Person *p, int *numberOfPersons, FILE* stream) { char buffer[BUFFER_SIZE]; char *result = NULL; while(feof(stream)==0) { /*Reads a line of the file*/ result = fgets(buffer,BUFFER_SIZE,stream); /*Checks if the line reading was successful*/ if(result!=NULL) { /*Interprets the line of the text and adds a new entry in the struct vector*/ sscanf(buffer,"%s %d %f %s",p[(*numberOfPersons)].name, &p[(*numberOfPersons)].age, &p[(*numberOfPersons)].salary, p[(*numberOfPersons)].email); /*Replaces the SPACE_REPLACEMENT character with space*/ ReplaceChar(p[(*numberOfPersons)].name,SPACE_REPLACEMENT,' '); /*Increments the Person counter*/ (*numberOfPersons)++; } } } int main(void) { Person persons[MAX_PERSONS] = { {"Clark Kent", 30, 3250.5, "superman@krypton.com"}, {"Peter Griffin", 40, 1250.0, "birdmaster@familyguy.com"}, {"Stewie Griffin", 3, 50000.0, "world_domination@familyguy.com"}, {"Eric Cartman", 12, 50000.0, "autoritah@southpark.com"}, {"Zapp Brannigan", 30, 200.5, "stargeneral@futurama.com"}, }; Person personsCopy[MAX_PERSONS]; int numberOfPersons = 0; FILE* stream = NULL; /*Opens the stream into <write text> mode*/ stream = fopen(PATH_TO_TXT_FILE,"wt"); if(stream!=NULL) { /*Save the struct vector into the text file*/ Persons_Save(&persons,5,stream); /*Closes the stream*/ fclose(stream); /*Reopens the stream into <read text> mode*/ stream = fopen(PATH_TO_TXT_FILE,"rt"); if(stream!=NULL) { /*Loads the text file into another struct vector*/ Persons_Load(&personsCopy, &numberOfPersons, stream); /*Closes the stream*/ fclose(stream); /*Prints the results*/ Persons_Print(&personsCopy,numberOfPersons); } } return 0; }A problem arises when you want to read from the text file a string that contains spaces because int sscanf ( const char * str, const char * format, ...) will not interpret it as a single string.
To solve this problem you can replace all space characters with a uncommon character for that string(in this example, I used '$' because is very uncommon when it comes to names).
No comments:
Post a Comment
Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!