我在重写第一个2.5KB的文件时遇到小问题。我的代码应该读取2KB和512字节到动态分配的内存,然后重写更大文件的特定字节。
f = fopen(argv[2], "rb");
if(f==NULL)
printf("File doesn't exist!");
fseek(f, 0, SEEK_SET);
data = calloc(2*1024+512, 1);
fread(data, 1, 2*1024+512, f);
fclose(f);
f = fopen(argv[1], "ab");
if(f==NULL)
printf("File doesn't exist!");
fseek(f, 0, SEEK_SET);
fwrite(data, 1, 446, f);
fseek(f, 512, SEEK_SET);
fwrite(((char*)data)+512, 1, 2*1024, f);
fclose(f);
当我尝试使用wb
模式时,它会删除第二个文件的内容。当我使用ab
模式并寻找文件的开头时,会在前面附加以前的内容。
有没有办法(使用标准C库)重写文件内容而不附加和复制写入文件的剩余内容?请帮忙。
答案 0 :(得分:3)
你想要ab+
。 +
表示更新模式。如果该文件存在,则只会打开它并且内容不会更改。 wb
本身只会删除原始文件并创建一个新文件。
答案 1 :(得分:2)
"rb"
模式打开位于开头的文件;最初的fseek()
是多余的。
第二次打开"ab"
打开文件,以便以附加模式书写。无论您事先执行fseek()
次操作,所有写操作都将发生在文件末尾。
您可以合理地使用模式"rb+"
打开文件一次以进行读写:
if ((f = fopen(argv[2], "rb+")) != 0)
{
char *data = calloc(2*1024+512, 1); // Missing error check
fread(data, 1, 2*1024+512, f); // Missing error check
// Modify data?
fseek(f, 0, SEEK_SET);
fwrite(data, 1, 446, f);
fseek(f, 512, SEEK_SET);
fwrite(((char*)data)+512, 1, 2*1024, f);
fclose(f);
}
在使用calloc()
之前,代码应检查data
是否成功;它还应该错误检查fread()
以确保它获得了预期的数据。据推测,中间的某些东西会修改从文件中读取的数据。
ISO / IEC 9899:2011(当前的C标准)对fopen()
的模式有所说明 - 除了x
标志之外,之前的标准大致相同,这是新的在C11:
§7.21.5.3
fopen
函数¶3参数
mode
指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。否则,行为是未定义的。 271)
r
打开文本文件进行阅读w
截断为零长度或创建用于编写的文本文件wx
创建用于编写的文本文件a
追加;打开或创建文本文件,以便在文件结尾处写入rb
打开二进制文件进行阅读wb
截断为零长度或创建用于写入的二进制文件wbx
创建用于编写的二进制文件ab
追加;打开或创建二进制文件以便在文件结尾处写入r+
打开文本文件进行更新(读写)w+
截断为零长度或创建文本文件以进行更新w+x
创建用于更新的文本文件a+
追加;打开或创建文本文件以进行更新,在文件结尾处写入r+b
或rb+
打开二进制文件进行更新(读写)w+b
或wb+
截断为零长度或创建二进制文件以进行更新w+bx
或wb+x
创建二进制文件以进行更新a+b
或ab+
追加;打开或创建二进制文件以进行更新,在文件结尾处写入271)如果字符串以上述序列之一开头,则实现可能会选择忽略 剩下的字符,或者它可能会用它们来选择不同类型的文件(其中一些可能不是 符合§7.21.2)中的属性。