Строка дублируется при печати в текстовый файл
Я пытаюсь записать строку предложения в текстовый файл, но он дублирует или что-то, когда я это делаю. Почему это так, и как заставить его печатать только один раз?
Отрывок программы:
FILE *memberAdd;
typedef struct {
char id[5], name[100];
} Member;
Member reg;
strcpy(reg.id, "M0001");
printf("Name: ");
rewind(stdin);
scanf("%[^\n]", reg.name);
memberAdd = fopen("member.txt", "a");
fprintf(memberAdd, "%s %s\n", reg.id, reg.name);
fclose(memberAdd);
Вывод в текстовый файл при запуске выше (reg.name
вход Test Name
):
M0001Test Name Тестовое имя
3 ответа
В вашем коде
strcpy(reg.id, "M0001");
это по одному. вы не можете хранить строки как "M0001"
(5 chars
и нулевой терминатор) в массиве 5 char
с помощью strcpy()
, Вы обращаетесь за пределы выделенной памяти, это вызывает неопределенное поведение.
квотирование C11
Глава §7.24.2.3
strcpy
функция копирует строку, на которую указываетs2
(включая завершающий нулевой символ) в массив, на который указываетs1
, [...]
Таким образом, подразумевается, что место назначения должно содержать исходную строку, включая нулевой терминатор. Вам не хватает памяти здесь, это доказано.:)
Вам также необходимо иметь память для хранения нулевого терминатора, если вы планируете использовать char
массив в виде строки. В этом случае вы можете увеличить член id
размерность для хранения завершающего нуля, например
char id[6];
Это:
char id[5];
strcpy(reg.id, "M0001");
переполнение буфера, strpcy()
запишет символ 0 в конце, переполняя ìd
массив. Вы получаете неопределенное поведение. Чтобы это исправить, нужно сделать строку идентификатора короче или, конечно, увеличить размер массива.
Каждая строка C должна заканчиваться некоторым байтом NUL (т.е. (char)0
).
Так "M0001"
занимает шесть (не 5!) байтов. И ваш char id[5]
поле недостаточно широкое Вы получаете переполнение буфера, случай неопределенного поведения. Вы должны были заявить
char id[6];
по крайней мере, как поле в Member
, Я действительно рекомендую сделать это больше, возможно char id[8];