这是我的代码,用于将文本文件内容绑定到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
答案 0 :(得分:1)
使用fscanf
将字符串读入包含8个字符的数组,这意味着您可以读取最多包含7个字符的字符串,因为最后一个字符必须是特殊的字符串终止字符'\0'
。
然而,在输入中你有例如字符串
FESTIVAL
正好是8个字符,但需要 9 个字符,包括终结符。这将导致fscanf
超出数组st
的范围。
更糟糕的是,您将这个9个字符的数据复制到一个只有7个字符的数组中,再次写出界限。
写出超出数组的范围会导致undefined behavior,并使整个程序形成错误。
答案 1 :(得分:0)
最明显的问题是:你正在阅读缓冲区
8 char
,但你的一些数据需要9(不要忘记尾随
'\0'
);然后将strcpy
放入7 char
的缓冲区中。为了
你输入的输入,你需要至少9个字符的缓冲区。你也是
想要以fscanf
的格式提供宽度参数,以便
无论输入如何,都要避免覆盖缓冲区。 (事实上,你
可能想要使用fgets
逐行读取,非常大
缓冲区,然后检查1)你实际读到的结尾了
line(最后一个字符应该是'\n'
),以及2)单词in
该行的字符数最多比缓冲区的大小少一个。
(显然,这在C ++中会非常简单。)