将 C 样式文件包装在流C++

Wrap C-style files in C++ stream

本文关键字:C++ 包装 文件包 样式 文件      更新时间:2023-10-16

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

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

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 << "Testn";
    fs << std::flush;
    fclose(f);
}

关于这一点需要注意的事项:

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

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

请注意,它永远不会将<<转换为fprintf(file, ...):结果将更类似于sprintf(buf, ...); fwrite(file, buf)