0
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);
}

ユーザーがセミナーのタイトルを入力する必要がある最初の fgets() は、関数を実行するたびにスキップされます。txtファイルから読み取る以前のfgets()がバッファに何かを残していると思いますか?これを修正する方法がわかりません...また、私はCとプログラミング全般の初心者なので、それが明らかな場合は...申し訳ありません:/

4

1 に答える 1

3

バッファオーバーフローを回避するために使用することを称賛しますが、まだ十分ではありfgetsませ:

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

のサイズtemp_stringは、割り当てたバッファーのサイズではなく、char ポインターのサイズです。つまり、おそらく最大で 4 文字 (64 ビット ポインターの場合は 8 文字) を読み取るだけで、残りは入力ストリームに残されます。

バッファのサイズを使用する必要があります (100 ですが、ハードコードされた値ではなく、定義された定数の方が適切です)。

または、多くのエッジ ケースを処理するこの getLine ルーチンを参照してください。


余談ですが、乗算は定義によってsizeof(char)常に保証されているため、乗算する必要はありません。乗算1を行うと、ソースコードが詰まるだけです。

mallocまた、特定の微妙なエラーを隠す可能性があるため、戻り値をキャストしないでください。theC は、 void *` の戻り値を他のポインター型に暗黙的に変換することができます。

注意すべきもう 1 つの点:バッファーをオーバーフローからfgets保護するために使用しているにもかかわらず、関数に対して同様の保護が適用されていません。temp_stringstrcpy

strcpyつまり、80文字の町の名前を入力できるようになり、20文字の構造フィールドに触れてはならない記憶が吹き飛ばされます.

于 2013-02-05T02:09:58.120 に答える