Это мой код для привязки содержимого текстового файла к связанному списку в C, с заданием на чтение все в порядке, но он допустил ошибку в fclose (f), стек вокруг переменной ‘st’ поврежден. Я не понимаю, как я могу это исправить?
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <iostream>
using namespace std;struct Nut
{
char Tu[7];
Nut * Tiep;
};Nut TD[26];
Nut *first;
void AddFirst(Nut *q, Nut *&first)
{
Nut *p;
p = new Nut;
if (first == NULL)
{
first = q;
return;
}
for (p = first; p->Tiep != NULL; p = p->Tiep)
p->Tiep = q;
}
void ReadData(Nut *ds[], int &n)
{
n = 0;
char old = '0';
FILE *f;
Nut *Tam;
Nut *Tu;
f = fopen("TD.txt", "r");
int dem = -1;
if (f == NULL)
cout << "File rong !!!";
else
{
while (!feof(f) == 1)
{
char st[8] = "";
fscanf(f, "%s", st);
Tam = new Nut();
strcpy(Tam->Tu, st);
char c = st[0];
if (c != old){
dem++;
ds[dem] = new Nut();
n++;
}
AddFirst(Tam, ds[dem]);
}
}
fclose(f);
}
Обновление 1:
Извините, я должен сделать это на C, но я использую Visual C ++, окончательная среда — C
файл данных, td.txt
ACCEPT
ADULT
APART
AUGUST
BACK
BAD
BOY
BREAK
CAT
CHEF
CHICKEN
COWBOY
CRY
DAD
DESIGN
DIE
DRAW
EAT
EMPTY
ERROR
EXPLORE
FAN
FELL
FESTIVAL
FULL
GAS
GIVE
GRAPHIC
Ты используешь fscanf
для чтения строк в массив, содержащий 8 символов, что означает, что вы можете прочитать строку длиной не более 7 символов, поскольку последний символ должен быть специальным символом завершения строки '\0'
,
Тем не менее, на входе у вас есть, например, строка
FESTIVAL
который ровно 8 символов, но нуждается 9 символы, включая терминатор. Это приведет к fscanf
писать за пределами массива st
,
Хуже всего то, что вы затем копируете эти 9-символьные данные в массив из 7 символов, снова выполняя запись без границ.
Запись за пределы массива приводит к неопределенное поведение, и делает всю вашу программу плохо сформированной.
Самая очевидная проблема: вы читаете в буфер
8 char
, но некоторые ваши данные требуют 9 (не забывайте конечный
'\0'
); ты тогда strcpy
это в буфер 7 char
, Для
ввод, который вы даете, вам нужны буферы не менее 9 символов. Вы тоже
хочу предоставить аргумент ширины в формате fscanf
, чтобы
Избегайте перезаписи буфера независимо от ввода. (На самом деле, вы
вероятно, хотите использовать fgets
, читать построчно, с очень большим
буфер, а затем проверьте, что 1) вы на самом деле прочитали до конца
строка (последний символ должен быть '\n'
) и 2) что слово в
строка содержит максимум на один символ меньше размера вашего буфера.
(Очевидно, что все это будет значительно проще в C ++.)