Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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
C 为什么这个程序不一次又一次地显示第一行?_C_Gcc_File Handling - Fatal编程技术网

C 为什么这个程序不一次又一次地显示第一行?

C 为什么这个程序不一次又一次地显示第一行?,c,gcc,file-handling,C,Gcc,File Handling,三个printf语句应显示三次“abc”。。但结果是:- abc def ghi 我知道我在某个地方的观念是错误的。请帮助。realloc()的用法不正确 abc def ghi 因为行是通过值传递的,所以不会更改。实际重新分配的内存在返回值中。因此,line一次又一次地保持不变,并且您一次又一次地看到相同的行编辑:刚刚意识到,即使这是一个bug,也不会导致重复行。其他观点仍然有效 更糟糕的是: 每次都会丢失新重新分配的指针,从而导致内存泄漏 您可能正在访问释放的内存,因为旧的行值在重新分配

三个printf语句应显示三次“abc”。。但结果是:-

abc
def
ghi
我知道我在某个地方的观念是错误的。请帮助。

realloc()的用法不正确

abc
def
ghi
因为
是通过值传递的,所以不会更改。实际重新分配的内存在返回值中。因此,
line
一次又一次地保持不变,并且您一次又一次地看到相同的行编辑:刚刚意识到,即使这是一个bug,也不会导致重复行。其他观点仍然有效

更糟糕的是:

  • 每次都会丢失新重新分配的指针,从而导致内存泄漏
  • 您可能正在访问释放的内存,因为旧的
    值在重新分配后可能会变得无效,如果它被重新分配到堆的不同部分
  • 您正在为每个字符重新分配内存,这可能是一个昂贵的操作
  • fgetc()
    前进文件指针(即“下一个要读取的字符所在的位置”)。这就是如何在循环中调用它并读取整行字符的方法

    在经过换行符后,它自然会移动到下一个字符,即下一行的开头

    您可以使用
    fseek()
    函数修改文件指针。例如,调用
    fseek(infle,0,SEEK\u SET)
    会将其重置为文件的开头,导致下一个
    fgetc()
    调用从文件的第一个字符重新开始


    但我正在按值传递文件指针。所以我应该一次又一次地得到输出“abc”

    啊,我理解你的困惑

    文件指针仅指向实际的文件结构。诸如当前偏移量之类的状态不是指针的一部分,而是内部结构的一部分


    考虑这一点的另一种方式是,表示文件的实际对象是file。要获得按引用传递语义,需要传递一个指向对象的指针。由于您是通过引用传递的,因此每一行都会从最后一行结束的地方开始。

    您的标题和问题完全相互矛盾。你在问什么问题?除了
    realloc
    问题之外,你不应该调用
    feof
    作为循环条件。您的循环结构应该是:
    int c;/*请注意,这是int,而不是char*/while((c=fgetc(infle))!=EOF){ /**…*/< /COD>参见解释。此外,不是重新创建轮子,而是考虑使用<代码> FGES,或者如果您想要一个动态分配缓冲器的版本,足够长的时间来容纳整个行,使用Chuck Falconer的公共域<代码> GDES< /Cord>函数:OK。我读到了C-FAQ……ld be void*tmp=realloc(line,i+1);if(tmp){line=tmp;}else{/*handle error*/}我会在这个+1答案中加上一句,你不应该为每个字符
    realloc
    ing。这是一个相对昂贵的过程。调整缓冲区大小有两种常用方法。1)有初始分配(例如1024字节)和增量大小(512字节),每次需要扩展缓冲区时添加。2)具有默认大小(例如64字节)并且每次realloc时都要加倍大小。哦,如果您想查看字符串,还应该在字符串末尾加上“\n”;printf通常使用缓冲输出。你们都是对的,不过我更愿意关注手头的问题,而不是用太多的信息压倒询问者。:@asveikau错误处理在提供的代码中缺失,但在在这个函数的上下文中,实际上没有必要使用临时指针:如果失败,您可以安全地分配到
    ,并返回NULL。实际上,您是对的,如果realloc未能分配新指针,它将不会接触原始指针。但是我正在按值传递文件指针。因此,我应该得到输出“abc”一次又一次..您混淆了术语。指向文件的指针与“文件指针”(也称为“文件位置指示符”)不同。您一次又一次地传递指向同一文件的指针,但文件位置指示符随着每次调用fgetc()而前进。正如aib所说,您必须使用fseek()重置它如果你想重新开始的话。是的。我得到了我真正想要的。非常感谢你。谢谢你告诉其他人更多的要点。。。
    
    abc
    def
    ghi
    
    realloc(line,i+1); // wrong
    
    // OK
    void *new_line = realloc(line,i+1);
    if (!new_line)
    {
        free(line);
        return NULL;
    }
    line = new_line;