I have a struct like so:
struct Office {
char city[50];
int employees;
char desc[200];
}
struct Office office[100];
Then I want to fill the office array within a loop until reach end of file.
here is my data:
Toronto
151: This is HQ
Vancouver
23: This is branch office
London
12: This is euro branch
Take this as an example:
Toronto
151: This is HQ
So here I want to parse it to struct:
city = "Toronto"
employees = 151
desc = "This is HQ"
Notice: After city name in the new line before the number of employess, there is TAB (4 spaces)
I have had an implementation like so, but seems it does not work properly:
int function LoadOffices(const char *f) {
int res = 1;
char buf[500];
char city[50];
int emp;
char desc[200];
struct Office offices[100];
FILE *fp = fopen(f, "r");
if (fp) {
while (fgets(buf, sizeof(line), fp) != nullptr) {
if (i == 0) {
rewind(fp);
}
i++;
if (fscanf(fp, "%[^\n]", city) == 1) {
strncpy(offices[i].city, city, 50);
} else if (fscanf(fp, "%d[^:]:%[^\n]", &emp, desc) == 2) {
offices[i].employees = emp;
strncpy(offices[i].desc, desc, 200);
}
}
res = 0;
} else {
res = 1;
}
fclose(fp);
return res;
}
I just want to know how to deal with TAB and empty lines
The structure of your program makes a huge difference in how easy it is to approach a problem.
For loading an array of any kind of struct
there is an idiom that you should use:
struct
struct
Here is what I suggest you work on:
bool LoadAnOffice( FILE * fp, struct Office * office );
// Attempt to read a single office from the open stream 'fp'
// Returns success or failure
bool LoadOffices( FILE * fp, struct Office offices[], size_t * num_offices, size_t max_num_offices );
// Fill an array of offices by loading them from the open stream 'fp'
// Returns the number of offices loaded in '*num_offices'
// Reads at most 'max_num_offices'
// Returns 'true' if EOF encountered, 'false' otherwise
You can even add a function to do it by opening a file as you wish:
bool LoadOfficesFromFile( const char * filename, struct Office offices[], size_t * num_offices, size_t max_num_offices )
{
FILE * f = fopen( filename, "r" );
if (!f) return false;
bool result = LoadOffices( f, offices, num_offices, max_num_offices );
fclose( f );
return result;
}
Thereafter your program can easily handle loading your offices from file:
int main(void)
{
#define MAX_OFFICES 100
struct Office offices[MAX_OFFICES];
size_t n_offices = 0;
if (!LoadOfficesFromFile( "offices.txt", offices, &n_offices, MAX_OFFICES ))
{
fprintf( stderr, "%s\n", "complain!" );
...
}
It isn't short , but it is a good way to modularize handling file I/O for structured types. You'll find yourself using some variation of this idiom over and over and over.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.