C 语言fseek, ftell调用失败(fseek返回非零值,ftell返回-1)

C 语言fseek. ftell调用失败(fseek返回非零值,ftell返回-1)


太长不看版

  • fseek调用失败,返回非零值,是因为传入的参数超过了文件尾,或者文件大于2G,需要使用fseek的64 bit版本_fseeki64.

  • ftell调用失败,返回-1,唯一一次遇到是因为文件大于2G,需要使用ftell的64bit版本,_ftelli64.

BUG重现

size_t offset = 0;
size_t file_data_size = 0,pos_start = 0,pos_end = 0;
unsigned char * buffer = NULL;
pos_start = ftell(fp);//此处正常
fseek(fp, 0L, SEEK_END);
pos_end = ftell(fp);//此处返回一个很大的值
file_data_size = pos_end - pos_start;

buffer = new unsigned char[file_data_size];

错误分析

  1. pos_start和pos_end此处应该是long。
  2. 文件大小超过了2G,应该使用64 bit的版本。

修改后

size_t offset = 0;
__int64 file_data_size = 0,pos_start = 0,pos_end = 0;
unsigned char * buffer = NULL;

pos_start = 0;
rnt_value = _fseeki64(fp, 0L, SEEK_END);
pos_end = _ftelli64(fp);
if (pos_end != -1 && pos_start != -1)
{
    file_data_size = pos_end - pos_start;
}
else
{
    std::cout << "error: fseek error\t" << __FILE__ << __LINE__ << std::endl;
    return false;
}           
buffer = new unsigned char[file_data_size];

_fseeki64(fp, pos_start, SEEK_SET);
fread(buffer, sizeof(unsigned char), file_data_size, fp);

修改分析

  1. pos应该定义为int64,而不是其他任何类型。
  2. 使用fseek和ftell的64 bit版本。

fseek与ftell

fseek
ftell

参考:C标准库,P249, P250

猜你喜欢

转载自blog.csdn.net/smallflyingpig/article/details/79432614