提问人:Rakesh Solanki 提问时间:5/20/2023 更新时间:5/20/2023 访问量:61
fseek 在“w”模式下返回 -1,并在 C 程序中使文件为空
fseek is returning -1 in "w" mode and making file blank in C program
问:
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
FILE* fp = fopen("sample.txt", "w");
if (fp == NULL)
return 1;
int error = 0;
if ((error = fseek(fp, -5, SEEK_END)) != 0)
{
printf("Error fseek failed: %d\n", error);
fclose(fp);
return 1;
}
fprintf(fp, "%d", 1);
fclose(fp);
return 0;
}
我的示例 .txt 文件:
adsfasdfasdfasfasfasfasdfasfasfasfas
asdfasdfasdfasdfasfadsfsadfadsfsafad
在上面的程序中,fseek 返回 -1 并使文件为空,并且与“w+”模式相同。相同的程序在“r+”中正常工作。我想知道 C 语言中的 fseek 和 file 模式之间有什么关系?我尝试搜索,但直到现在我在网上什么也没找到。
答:
模式,并将删除 fle 的内容(如果存在),以便您将拥有一个长度为零的新文件。该模式不会执行此操作,但会保留任何现有文件内容。fopen
"w"
"w+"
"r+"
所有这些都在 的文档中进行了说明。fopen
如果文件的长度为零,则函数调用
fseek(fp, -5, SEEK_END)
会失败,因为没有这样的偏移量。
此外,还值得注意的是,根据 ISO C11 标准的 §7.21.9.2 ¶4,该函数调用将调用未定义的行为。当文件以文本模式打开时(如您所做),唯一允许的偏移量是对 ftell
的函数调用的值或上一个返回值。这在Microsoft Windows上尤其是一个问题,因为它在每行的末尾使用,以文本模式转换为文本模式。但是,这在不区分文本模式和二进制模式的 POSIX 平台上不是问题。POSIX平台始终在两种模式下使用。fseek
fseek
0
\r\n
\n
\n
此规则在 的文档中也有提及。fseek
但是,在实践中,在文本模式下使用非零偏移量可能不是问题,只要您不跳转到 a 和字符之间的偏移量,并且如果您考虑到这一点,在 Windows 上,一行结尾算作两个偏移量,即使在文本模式下被翻译为。fseek
\r
\n
\r\n
\r\n
\n
评论
w
w+
fopen
fseek
fseek
fopen
+
"r+"
fseek
替换为 它可能会打印或类似。printf("Error fseek failed: %d\n", error);
perror("fseek");
fseek: Invalid argument
您通过打开文件来截断文件,然后他们尝试从末尾返回 5 个字符(在空文件中)。在普通文件中,这是无法做到的。"w"
当打开它时,文件的内容被保留,并且从末尾向后查找时,5 个步骤会成功(使用您显示的内容)。"r+"
评论