【问题标题】:Wrap C-style files in C++ stream [duplicate]在 C++ 流中包装 C 样式文件 [重复]
【发布时间】:2013-10-09 11:49:40
【问题描述】:

对于一个项目,我必须使用 C 风格的文件类型进行读/写。它可以是普通的 FILE,或 gzfile 的 C 版本等。我仍然喜欢使用 C++ 流的便利。是否有一个流类可以在内部重定向到 C 风格的文件操作?所以myfile << hex << myint 最终会变成fprintf("%a", myint) 或类似的东西?

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    没有标准的,但如果你必须这样做,那么你将不得不使用非标准的东西。

    GCC 的标准库包含一个 streambuf 类型,__gnu_cxx::stdio_filebuf,它可以用 FILE*(或文件描述符)构造,您可以用它来替换 fstream 的 streambuf,或者只使用普通的iostream 例如

    #include <stdio.h>
    #include <ext/stdio_filebuf.h>
    #include <fstream>
    
    int main()
    {
        FILE* f = fopen("test.out", "a+");
        if (!f)
        {
            perror("fopen");
            return 1;
        }
        __gnu_cxx::stdio_filebuf<char> fbuf(f, std::ios::in|std::ios::out|std::ios::app);
        std::iostream fs(&fbuf);
        fs << "Test\n";
        fs << std::flush;
        fclose(f);
    }
    

    注意事项:

    • stdio_filebuf 不能超出范围,而 iostream 仍在引用它
    • 您需要手动关闭FILE*stdio_filebuf 在从FILE* 构造时不会这样做
    • 请务必在关闭FILE* 之前刷新流,否则stdio_filebuf 的缓冲区中可能有未写入的数据在FILE* 关闭后无法写入。

    【讨论】:

    • 在您当前的代码示例中,fclose() 将在流和缓冲区的析构函数之前调用。即使先刷新,这也可能是一个未定义的行为:您应该添加一个在调用 fclose() 之前结束的 {} 块。
    • @Medinoc 这是一个库扩展。检查源代码。我冒险猜测 Jonathan,作为 libstdc++ 的作者,知道如何使用它的扩展 ;-)
    • 好吧,我已经很久没有使用这些类了,所以我可能弄错了。 Medinoc 的建议是个好主意,虽然我很确定它不会导致未定义的行为,但您可能会丢失数据并且errno 将被设置
    【解决方案2】:

    您需要的是在 C 文件上写入的 streambuf 类的实现。如果 C++ 标准中还没有一个(这会让我有点失望,但我并不感到惊讶),你可以创建一个并覆盖正确的方法。

    请注意,它永远不会将&lt;&lt; 翻译为fprintf(file, ...):结果将更类似于sprintf(buf, ...); fwrite(file, buf)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多