在 fseek() 之前保持 FILE 指针的位置
hold position of FILE pointer before fseek()
我正在尝试编写一个 C 函数,它从文件中读取第一行文本,然后使用 fseek()
和 ftell()
来获取文件剩余部分的大小(文件减去第一行)。
我的想法是用第二个FILE *fp1
抢到原来FILE *fp
的位置,用fseek()
把fp1
送到文件末尾,这样我就不必移动我原来的 fp
并失去它的位置。
这是我的代码。编译器告诉我不能将 fp1
分配给 fp
,因为 fp1
是 FILE*
而 fp
是 struct FILE*
。
我可以通过这种方式实现我想要做的事情吗?
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);
这只是将指针复制到文件句柄。正确的方法是在移动之前保存 ftell 结果,并在移动到文件末尾后再次移动回来。
所以:
long saved = ftell(fp);
fseek(fp, 0, SEEK_END);
*file_size = ftell(fp);
fseek(fp, saved, SEEK_SET);
您的定义没有定义 2 FILE *
个指针:
FILE *fp, fp1;
fp
是 FILE *
,但 fp1
被定义为 FILE
类型。
您不能以这种方式定义 FILE
对象,它们只能从 fopen()
获得。它们的状态不能通过复制 FILE
对象来保存,它太复杂了,并且除了 FILE
对象之外还使用了其他资源,这可能是一个不完整的类型。
好消息是,您可以使用 ftell()
将当前偏移量保存在 fp
中,然后搜索到末尾以尝试获取文件大小,然后通过另一个调用恢复流位置fseek()
:
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);
但是你要注意这个方法并不靠谱:
- 不能保证文本文件。
- 它可能不适用于设备、管道、终端、特殊文件...
您应该尝试修改您的方法,使其不需要知道文件大小。
我正在尝试编写一个 C 函数,它从文件中读取第一行文本,然后使用 fseek()
和 ftell()
来获取文件剩余部分的大小(文件减去第一行)。
我的想法是用第二个FILE *fp1
抢到原来FILE *fp
的位置,用fseek()
把fp1
送到文件末尾,这样我就不必移动我原来的 fp
并失去它的位置。
这是我的代码。编译器告诉我不能将 fp1
分配给 fp
,因为 fp1
是 FILE*
而 fp
是 struct FILE*
。
我可以通过这种方式实现我想要做的事情吗?
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);
这只是将指针复制到文件句柄。正确的方法是在移动之前保存 ftell 结果,并在移动到文件末尾后再次移动回来。
所以:
long saved = ftell(fp);
fseek(fp, 0, SEEK_END);
*file_size = ftell(fp);
fseek(fp, saved, SEEK_SET);
您的定义没有定义 2 FILE *
个指针:
FILE *fp, fp1;
fp
是 FILE *
,但 fp1
被定义为 FILE
类型。
您不能以这种方式定义 FILE
对象,它们只能从 fopen()
获得。它们的状态不能通过复制 FILE
对象来保存,它太复杂了,并且除了 FILE
对象之外还使用了其他资源,这可能是一个不完整的类型。
好消息是,您可以使用 ftell()
将当前偏移量保存在 fp
中,然后搜索到末尾以尝试获取文件大小,然后通过另一个调用恢复流位置fseek()
:
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);
但是你要注意这个方法并不靠谱:
- 不能保证文本文件。
- 它可能不适用于设备、管道、终端、特殊文件...
您应该尝试修改您的方法,使其不需要知道文件大小。