ad在缓冲区中构建扫描字符串以实现此目的 char fmt[64]; snprintf(fmt, sizeof(fmt), "%%%d[^\n]", size); check = fscanf(fp, fmt, a);
但是您还必须添加代码来检查您是否真正阅读了完整的行。您可能希望进行的修复是将分配的大小增加1,以说明终止的ad在缓冲区中构建扫描字符串以实现此目的 char fmt[64]; snprintf(fmt, sizeof(fmt), "%%%d[^\n]", size); check = fscanf(fp, fmt, a);,c,memory,glibc,corruption,C,Memory,Glibc,Corruption,但是您还必须添加代码来检查您是否真正阅读了完整的行。您可能希望进行的修复是将分配的大小增加1,以说明终止的NUL。但是,如果解决了这个问题,您的程序将处于无限循环中。这是因为您的getc循环没有检查EOF。你需要补充一点 int c; while ((c = getc(fp)) != '\n') { if (c == EOF) { end = 1; break; } size = size + 1; } if (!end) { //
NUL
。但是,如果解决了这个问题,您的程序将处于无限循环中。这是因为您的getc
循环没有检查EOF
。你需要补充一点
int c;
while ((c = getc(fp)) != '\n') {
if (c == EOF) {
end = 1;
break;
}
size = size + 1;
}
if (!end) {
//...
}
您的第二个扫描字符串%[^\EOF]
可能不是您认为的意思。无论如何,没有真正的方法告诉fscanf
扫描到文件末尾。如果检查失败
,只需报告失败并退出即可。然后,您可以稍后找出您的输入导致其失败的原因,并修复输入
fscanf
使用起来很棘手,因为处理自由格式输入时存在各种危险。缓冲区溢出是一个问题,但如果输入的格式与您期望的格式不同,则函数也可能会出现意外行为。这就是为什么程序员会建议无条件地将输入读入缓冲区并解析缓冲区,而不是使用fscanf
同时读取和解析输入
您可以实现一些简单的代码,仅使用fgets
来获取一行代码,而代价是复制一些代码。如果缓冲区没有以\n
结尾,则可以将缓冲区的大小调整得更大,然后继续读取
size_t size = 256;
char *line = malloc(size);
line[size-2] = '\0';
while (fgets(line, size, fp) != 0) {
while (line[size-2] && line[size-2] != '\n') {
char *bigger_line = realloc(line, 2*size);
assert(bigger_line); // rudimentary error handling
size *= 2;
line = bigger_line;
line[size-2] = '\0';
if (fgets(line + size/2 - 1, size/2 + 1, fp) == 0) {
// last line doesn't end with '\n'
break;
}
}
//... handle input line
}
//...
free(line);
这意味着您损坏了堆或对已释放的指针调用了
free
,glibc检测到并报告了它。为什么会在文件分析过程中发生这种情况?“autore”之前每行文本的O.O:Hennessy,John L。;作者:帕特森,大卫A。;titolo:计算机架构,第五版:定量方法;editore:摩根·考夫曼;安诺:2011年;注:;collocazione:HHH.56;CA,旧金山;财政部说明:第896页,softcov,7 1/2 X 9 1/4公司它工作得很好,因为您正在覆盖已分配的缓冲区的末尾。fscanf()不接受正则表达式,因此这些行不符合您的想法。fscanf
甚至不应在此处使用。只需使用fgets
。那些%[
说明符不是正则表达式;它们是scanf的一部分,但OP对它们的使用是不正确的。@ArrigoPierotti:我只是警告您远离fscanf
。我编辑了问题的原因。这不是字符串长度的问题……其他行更长或更短,没有顺序,也没有检测到问题。。。@ArrigoPierotti:溢出缓冲区会导致未定义的行为,而未定义意味着它可能工作,也可能不工作。
int c;
while ((c = getc(fp)) != '\n') {
if (c == EOF) {
end = 1;
break;
}
size = size + 1;
}
if (!end) {
//...
}
size_t size = 256;
char *line = malloc(size);
line[size-2] = '\0';
while (fgets(line, size, fp) != 0) {
while (line[size-2] && line[size-2] != '\n') {
char *bigger_line = realloc(line, 2*size);
assert(bigger_line); // rudimentary error handling
size *= 2;
line = bigger_line;
line[size-2] = '\0';
if (fgets(line + size/2 - 1, size/2 + 1, fp) == 0) {
// last line doesn't end with '\n'
break;
}
}
//... handle input line
}
//...
free(line);