Вы можете использовать что-то вроде этого, чтобы прочитать одну запись школы из FILE*
, который вы предоставляете:
bool School_read(School* s, FILE* in) {
int scan = fscanf(in, " %m[^,\n], %m[^\n]", &s->name, &s->state);
// the fscanf format string:
// <space> = skip leading whitespaces (like a newline from the line before)
// %m[^,\n] = read a string until, but not including, "," or "\n" m = allocate space for it
// , = expect a comma and discard it
// %m[^\n] = read a string until, but not including, "\n" and allocate space for it
// just a debug print
fprintf(stderr, " -- got %d hits, >%s< >%s<\n", scan, s->name, s->state);
if(scan<2) {
// not a complete scan, failure
if(scan==1) {
// apparently, we got one match, free it
free(s->name);
s->name = NULL;
}
return false;
}
return true;
}
Я не знаю, насколько широко распространена поддержка модификатора 'm', который динамически распределяет памятьдля строк, хотя.Последние компиляторы gcc и clang поддерживают его в любом случае.
Вы также можете создавать функции для создания и уничтожения школы:
School* School_create() {
School* s = malloc(sizeof(School));
if(s!=NULL) {
s->name = NULL;
s->state = NULL;
}
return s;
}
void School_destroy(School** sp) {
if(sp) {
School* s = *sp;
if(s) {
if(s->state) free(s->state);
if(s->name) free(s->name);
free(s);
}
*sp = NULL;
}
}
.. и комбинировать их все:
School* School_create_and_read(FILE* in) {
School* s = School_create();
if(s) {
if(School_read(s, in)==false) {
School_destroy(&s);
}
}
return s;
}
Так в вашей функции заполняется массив школ:
void input_schools(FILE* IN, School** Sch, int k) {
School* s;
while( (s=School_create_and_read(IN)) ) {
// s is a valid School pointer
// store it in your array
}
}