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!