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