简体   繁体   中英

Why does it skip fgets()?

typedef struct {
int serial_no;
char s_name[100];
char s_street[50];
char s_town[20];
int s_speaker_no;
int max_no_teachers;
int no_applied_teachers;
} type_seminar;


void add_seminar() {
int seminar_number, temp_int;
char *temp_string;
temp_string = (char*) malloc(100 * sizeof(char));

FILE *f_sem;
FILE *f_school;
f_sem = fopen("seminars.bin", "a");
f_school = fopen("school_list.txt", "r");

fgets(temp_string, 10, f_school);
seminar_number = (atoi(temp_string) + 1);

type_seminar *temp_s = (type_seminar*) malloc(sizeof(type_seminar));
temp_s->serial_no = seminar_number;
temp_s->no_applied_teachers = 0;
temp_s->s_speaker_no = 0;

printf("Enter the seminar title: \n");
fgets(temp_string, sizeof temp_string, stdin);
strcpy(temp_s->s_name, temp_string);

printf("Enter the seminar address(street and house number): \n");
fgets(temp_string, sizeof temp_string, stdin);
strcpy(temp_s->s_street, temp_string);

printf("Enter the town (where the seminar will be held) : \n");
fgets(temp_string, sizeof temp_string, stdin);
strcpy(temp_s->s_town, temp_string);

printf("Enter the maximum number of the seminar participants : \n");
fgets(temp_string, sizeof temp_string, stdin);
temp_int = (atoi(temp_string));
temp_s->max_no_teachers = temp_int;

free(temp_s);
free(temp_string);
fclose(f_school);
fclose(f_sem);
}

The first fgets() where user should enter the seminar title gets skipped everytime I run the function. I presume the previus fgets() that reads from the txt file leaves something in the buffer? I have no idea how to fix this though... Also, I'm a newbie at C and programming in general, so if it's something obvius... sorry :/

Kudos for using fgets to avoid buffer overflows, but you're not quite there:

char *temp_string;
:
temp_string = (char*) malloc(100 * sizeof(char));
:
fgets(temp_string, sizeof temp_string, stdin);

The size of temp_string is the size of a char pointer, not the size of the buffer you've allocated. That means you're most likely just reading four (or possibly eight if you have 64-bit pointers) characters maximum, then the rest are left in the input stream.

You should be using the size of the buffer (100, though it would be better as a defined constant rather than a hard-coded value).

Alternatively, have a look at this getLine routine , which handles a lot of edge cases.


And, just as an aside, you don't need to multiply by sizeof(char) since that's always guaranteed to be 1 by definition - doing the multiply just clogs up your source code.

You also shouldn't cast the return value from malloc since it can hide certain subtle errors. C is quite capable of implicitly converting the void *` return value to any other pointer type.

The other thing you should watch out for: even though you're using fgets to protect the temp_string buffer from overflow, no similar protection has been put in place for your strcpy functions.

That means it will allow you to enter an 80-character town name, which will then blow away memory it's not supposed to touch as you strcpy that into the 20-character structure field.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM