C 将文件指针的位置保持在fseek()之前
我正在尝试编写一个C函数,从文件中读取第一行文本,然后使用C 将文件指针的位置保持在fseek()之前,c,file-io,fseek,C,File Io,Fseek,我正在尝试编写一个C函数,从文件中读取第一行文本,然后使用fseek()和ftell()获取文件其余部分的大小(文件减去第一行) 我的想法是使用第二个文件*fp1来获取原始文件*fp的位置,并使用fseek()将fp1发送到文件末尾,这样我就不必移动原始fp,并失去其位置 这是我的密码。编译器告诉我不能将fp1分配给fp,因为fp1是文件*,fp是结构文件* 我能通过这种方式实现我的目标吗 FILE *fp, fp1; fp = fopen(filename, "r"); if (!fp)
fseek()
和ftell()
获取文件其余部分的大小(文件减去第一行)
我的想法是使用第二个文件*fp1
来获取原始文件*fp
的位置,并使用fseek()
将fp1
发送到文件末尾,这样我就不必移动原始fp
,并失去其位置
这是我的密码。编译器告诉我不能将fp1
分配给fp
,因为fp1
是文件*
,fp
是结构文件*
我能通过这种方式实现我的目标吗
FILE *fp, fp1;
fp = fopen(filename, "r");
if (!fp)
return 0;
fscanf(fp, "%1d", m); //Lines 15-18 read the first line of the file
fscanf(fp, "%*1c");
fscanf(fp, "%1d", n);
fscanf(fp, "%*1c");
fp1 = fp; //<---------- This is my problem.
//how do I set fp1 to the same place in the
//file as fp?
fseek(fp1, 0, SEEK_END);
*file_size = ftell(fp1);
文件*fp,fp1;
fp=fopen(文件名,“r”);
如果(!fp)
返回0;
fscanf(fp,“%1d”,m)//第15-18行读取文件的第一行
fscanf(fp,“%*1c”);
fscanf(fp,“%1d”,n);
fscanf(fp,“%*1c”);
fp1=fp// 这只是将指针复制到文件句柄。正确的方法是在移动前保存ftell结果,在移动到文件末尾后,再次向后移动
因此:
这只是将指针复制到文件句柄。正确的方法是在移动前保存ftell结果,在移动到文件末尾后,再次向后移动
因此:
您的定义没有定义2个文件*
指针:
FILE *fp, fp1;
fp
是文件*
,但fp1
被定义为文件
类型
您不能用这种方式定义FILE
对象,它们只能从fopen()
获取。它们的状态无法通过复制文件
对象来保存,这太复杂了,除了文件
对象之外,还使用了其他资源,可能是不完整的类型
好消息是,您可以使用ftell()
将当前偏移量保存在fp
中,并搜索到底以尝试获取文件大小,然后通过另一次调用fseek()
恢复流位置:
但您应该注意,这种方法不可靠:
- 对于文本文件,这是不保证的
- 它可能不适用于设备、管道、终端、特殊文件
您应该尝试修改您的方法,使其不需要知道文件大小。您的定义没有定义2个文件*
指针:
FILE *fp, fp1;
fp
是文件*
,但fp1
被定义为文件
类型
您不能用这种方式定义FILE
对象,它们只能从fopen()
获取。它们的状态无法通过复制文件
对象来保存,这太复杂了,除了文件
对象之外,还使用了其他资源,可能是不完整的类型
好消息是,您可以使用ftell()
将当前偏移量保存在fp
中,并搜索到底以尝试获取文件大小,然后通过另一次调用fseek()
恢复流位置:
但您应该注意,这种方法不可靠:
- 对于文本文件,这是不保证的
- 它可能不适用于设备、管道、终端、特殊文件
您应该尝试修改您的方法,这样它就不需要知道文件大小。谢谢您的回复。使用SEEK_SET参数对fseek()的最后一次调用不会将fp重置回文件的开头吗?我试着不那样做。没关系,我看到你已经把储蓄作为一个补偿放进去了。我采纳了你的建议,效果很好。非常感谢你!请注意,此方法不是获取文件大小的可靠方法。它不适用于设备、管道、终端。。。文本文件不保证。谢谢回复。使用SEEK_SET参数对fseek()的最后一次调用不会将fp重置回文件的开头吗?我试着不那样做。没关系,我看到你已经把储蓄作为一个补偿放进去了。我采纳了你的建议,效果很好。非常感谢你!请注意,此方法不是获取文件大小的可靠方法。它不适用于设备、管道、终端。。。对于文本文件,这是不保证的。您可以通过将fp1
正确声明为指针来修复编译错误-缺少*
。即文件*fp,*fp1代码>。但这不是保存文件位置的正确方法(两个指针将引用相同的打开流,因此文件位置相同)。不要发布带有行号的代码,这不方便剪切和粘贴以进行测试。您可以通过将fp1
正确声明为指针来修复编译错误-缺少*
。即文件*fp,*fp1代码>。但这不是保存文件位置的正确方法(两个指针将引用相同的打开流,因此文件位置相同)。不要发布带有行号的代码,这不方便剪切和粘贴以进行测试。我合并了您的错误检查,谢谢。如果我使用C++,我会用CIN。PEEK()来查找EOF,但是我不太精通C。是否使用fOpen-()保持类似的EOF标记?我想我关于这方面的进一步问题不一定是这个问题的一部分。fopen
不维护eof标志。在C语言中,通过尝试读取文件*
,您才知道自己处于流的末尾。您可以这样写:intpeek(FILE*fp){intc=getc(fp);if(c!=EOF)ungetc(c,fp);返回c;}
并使用if(peek(fp)==EOF)
作为文件结尾的测试。我合并了您的错误检查,谢谢。如果我使用C++,我会用CIN。PEEK()来查找EOF,但是我不太精通C。是否使用fOpen-()保持类似的EOF标记?我想我关于这方面的进一步问题不一定是这个问题的一部分。fopen
不维护eof标志。在C中,您可以继续
long saved = ftell(fp);
*file_size = -1; // file size may be impossible to retrieve
if (fseek(fp, 0, SEEK_END) != -1) {
*file_size = ftell(fp);
}
fseek(fp, saved, SEEK_SET);