0

所以给定一个包含 100 个字节的二进制文件。我很确定 INVALID 应该导致错误,但为什么不呢?我很困惑,一次 INVALID 应该会引发语义错误,对吗?还是我误会了什么

/* VALID */  fseek(fp, sizeof(char) * 2, SEEK_SET);
/* VALID */  fseek(fp, -2 * sizeof(char), SEEK_END);
/* INVALID */fseek(fp, sizeof(char)* 2, SEEK_END);
/* INVALID */fseek(fp, -2 * sizeof(char), SEEK_SET);
/* INVALID */fseek(fp, 50, SEEK_CUR);
/* VALID */  fseek(fp, -50, SEEK_CUR);
/* INVALID */ fseek(fp, 51, SEEK_CUR);
/* INVALID */ fseek(fp, -51, SEEK_CUR);
4

2 回答 2

2

你在说什么“语义错误”?

无效的文件位置将导致fseek失败,这将由 . 的返回值指示fseek。您必须接收该值并对其进行分析以确定函数是否成功。您上面的代码完全忽略了fseek.

请记住,标准库并不要求所有平台都支持SEEK_END定位。平台可能不知道文件末尾的确切位置(直到您在读取文件时实际碰到它)。例如,某些文件系统可能不会以字节为单位存储确切的文件大小,而是存储该文件占用了多少“块”或“扇区”,这只能作为近似的文件大小。出于这个原因,语言规范声明SEEK_END不能保证对定位进行有意义的支持。

还要记住,在某些平台上,可能完全允许在为写入而打开的文件末尾寻找过去。随后的写入操作将在新位置写入数据,同时用零填充“间隙”。

于 2012-12-09T01:48:44.110 回答
0

我不知道您使用的是哪种操作系统(您说“二进制文件”的事实表明它是 Windows),但在基于 Unix 的系统上,“查找”操作实际上并没有立即执行任何操作。所以它不太可能崩溃。

以下是lseek函数描述的摘录,这是fseek和朋友使用的核心 Unix 函数,根据W. Richard Stevens在 Unix 环境中的高级编程:

每个打开的文件都有一个关联的“当前文件偏移量”,通常是一个非负整数,用于测量从文件开头开始的字节数。读写操作通常从当前文件偏移量开始,并导致偏移量递增...

lseek仅记录内核中的当前文件偏移量——它不会导致任何 I/O 发生。然后,此偏移量供下一次读取或写入操作使用。

简而言之,fseek改变的东西很可能只是结构内的一个整数变量。只有在请求实际的 I/O 操作时,Unix 内核才会访问文件系统。所以“不可能”的位置不会导致崩溃。

于 2012-12-09T02:26:57.953 回答