4

This creates the file but it doesn't write anything.

std::ofstream outstream;
FILE * outfile;

outfile = fopen("/usr7/cs/test_file.txt", "w");

__gnu_cxx::stdio_filebuf<char> filebuf(outfile, std::ios::out);
outstream.std::ios::rdbuf(&filebuf);

outstream << "some data";
outstream.close();
fclose(outfile);

I know there are other easy solutions to achieve the output, but i need to use this non-standard filebuf to lock a file while editing, so that other process can't open the file. I don't know why this is not working.

  • Have you tried actually opening `outstream`? – David G Mar 06 '14 at 03:00
  • I think you should create an `std::ostream` and construct it from the buffer, as in `std::ostream outstream(&filebuf)`, so you won't have to call `open()`/`close()` for no real reason. If you do that you also want need to do `outstream.std::ios::rdbuf(&filebuf);` as well. – David G Mar 06 '14 at 03:02
  • Sorry for not describing the reason to use this _gnu non-standard filebuf. I know other easy solutions can produce the output but i am using this approach to lock a file while editing; so that other process can't open the text file. – user3375257 Mar 06 '14 at 03:18
  • Why aren't you just using `std::ostream` here? If the `std::ofstream` is not opened then attempting to write anything will not work. – David G Mar 08 '14 at 16:27

1 Answers1

2

std::ostream already has a constructor doing the right thing:

#include <ext/stdio_filebuf.h>
#include <iostream>
#include <fcntl.h>

int main() {
    auto file = fopen("test.txt", "w");
    __gnu_cxx::stdio_filebuf<char> sourcebuf(file, std::ios::out);
    std::ostream out(&sourcebuf);
    out << "Writing to fd " << sourcebuf.fd() << std::endl;
}

Remember that stdio_filebuf won't close the FILE* when it is destroyed, so remember to do that yourself if you need it.

Benno
  • 5,288
  • 5
  • 42
  • 60
  • > Remember that stdio_filebuf won't close the FILE* when it is destroyed, so remember to do that yourself if you need it. -- gcc docs say that stdio_filebuf destructor "Closes the external data stream if the file descriptor constructor was used." https://gcc.gnu.org/onlinedocs/libstdc%2B%2B/libstdc%2B%2B-api-4.6/a00068.html#a331254f7330187859fb6d823bfa8b1a0 – Boris Glick Sep 26 '18 at 15:33
  • @BorisGlick A file descriptor is different from a file stream `FILE*`. gcc docs say that "This constructor associates a file stream buffer with an open C FILE*. The FILE* will not be automatically closed when the stdio_filebuf is closed/destroyed." See https://gcc.gnu.org/onlinedocs/libstdc%2B%2B/libstdc%2B%2B-api-4.6/a00068.html#a197c58345703b4c82256fe5c1574273f – Kubo Takehiro Jan 06 '23 at 05:58