【问题标题】:cant write to file after using fgetc/getc (Windows)使用 fgetc/getc (Windows) 后无法写入文件
【发布时间】:2016-09-09 07:09:06
【问题描述】:

我正在 Windows (VS 2010) 上使用 fgetc 开发一个简单的程序,并且我认识到在使用此功能后(与 getc 的行为相同)尽管我以适当的权限打开它,但我无法写入文件.

这是我编写的一个简单程序,用于检查到底发生了什么:

int main(int argc, char * argv[]) 
{
    FILE *f = NULL;
    char ch = 0;
    int bytes = 0;

    f = fopen(argv[1], "r+");
    ch = fgetc(f);
    bytes = fwrite("1234", sizeof(char), 4, f);
    printf("%d", bytes);
    fflush(f);
    fclose(f);

    system("PAUSE");
    return 0;
}

程序打印 4 并退出,没有任何错误,但文件内容保持不变。 经过一番研究后,我发现如果我添加这一行(即“什么都不做”):

fseek(f, 0, SEEK_CUR);

程序按预期运行,文件内容发生了变化。

添加此行后的所有代码:

int main(int argc, char * argv[]) 
{
    FILE *f = NULL;
    char ch = 0;
    int bytes = 0;

    f = fopen(argv[1], "r+");
    ch = fgetc(f);
    fseek(f, 0, SEEK_CUR)
    bytes = fwrite("1234", sizeof(char), 4, f);
    printf("%d", bytes);
    fflush(f);
    fclose(f);

    system("PAUSE");
    return 0;
}

有谁知道为什么会发生这种情况以及如何解决?

非常感谢, 哈南。

【问题讨论】:

标签: c windows file


【解决方案1】:

它不起作用,因为 C 标准(C11 草案 n1570 7.21.5.3 in 开放 功能第 7 段;以及所有以前的版本)说它不必工作。

当以更新模式打开文件时( + 作为第二个或第三个字符 更多 列表 模式 参数值),输入和输出都可以在 关联的流。但是,输出不得直接跟在输入后面没有 干预电话 fflush 函数或文件定位函数( fseek , fsetpos ,要么 rewind ),并且 input 后​​面不能直接跟 output 后​​面没有 干预对文件定位函数的调用,除非输入操作遇到 end-of-file [--]


请注意,如果文件最初是,则fgetc 将返回EOF 并且"1234" 将被写入。

【讨论】:

  • 那么如果我想根据我阅读的内容在文件中写一些东西我需要做什么。例如,如果我想用 'b' 替换文件中 'a' char 之后的每个字节(如果文件的内容是“asdfasdf”,我希望它是“abdfabdf”)
  • 啊,现在更棘手了。你不能向后寻找;相反,按照标准,您必须使用 ftell 来告诉文件位置 before fgetc;然后在fgetc 之后使用fseekSEEK_SET 寻找它。总而言之,如果你需要做很多这些修改,使用操作系统特定的机制来映射文件会更值得。
【解决方案2】:

来自https://msdn.microsoft.com/en-us/library/yeby3zcb.aspx

当“r+”、“w+”或“a+”访问类型被指定时,读取和写入都被启用(文件被称为为“更新”而打开)。但是,当你从读切换到写时,输入操作必须遇到一个EOF标记。如果没有 EOF,则必须使用对文件定位函数的干预调用。文件定位函数有 fsetpos、fseek 和 rewind。当您从写入切换到读取时,您必须使用对 fflush 或文件定位函数的干预调用

因此,因为您可能还没有达到 EOF,所以您需要定位搜索位置,这样您对 fseek 的调用正是您所需要的。

fgetc 的返回码上的 cmets 也很重要,但目前不会影响您的代码。

【讨论】:

    猜你喜欢
    • 2020-07-15
    • 1970-01-01
    • 2017-03-04
    • 2021-02-13
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    相关资源
    最近更新 更多