Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ad在缓冲区中构建扫描字符串以实现此目的 char fmt[64]; snprintf(fmt, sizeof(fmt), "%%%d[^\n]", size); check = fscanf(fp, fmt, a);_C_Memory_Glibc_Corruption - Fatal编程技术网

ad在缓冲区中构建扫描字符串以实现此目的 char fmt[64]; snprintf(fmt, sizeof(fmt), "%%%d[^\n]", size); check = fscanf(fp, fmt, a);

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) { //

但是您还必须添加代码来检查您是否真正阅读了完整的行。您可能希望进行的修复是将分配的大小增加1,以说明终止的
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);