Getting a File* from a Std::Fstream

Getting a FILE* from a std::fstream

The short answer is no.

The reason, is because the std::fstream is not required to use a FILE* as part of its implementation. So even if you manage to extract file descriptor from the std::fstream object and manually build a FILE object, then you will have other problems because you will now have two buffered objects writing to the same file descriptor.

The real question is why do you want to convert the std::fstream object into a FILE*?

Though I don't recommend it, you could try looking up funopen().

Unfortunately, this is not a POSIX API (it's a BSD extension) so its portability is in question. Which is also probably why I can't find anybody that has wrapped a std::stream with an object like this.

FILE *funopen(
const void *cookie,
int (*readfn )(void *, char *, int),
int (*writefn)(void *, const char *, int),
fpos_t (*seekfn) (void *, fpos_t, int),
int (*closefn)(void *)
);

This allows you to build a FILE object and specify some functions that will be used to do the actual work. If you write appropriate functions you can get them to read from the std::fstream object that actually has the file open.

Retrieving file descriptor from a std::fstream

You can go the other way: implement your own stream buffer that wraps a file descriptor and then use it with iostream instead of fstream. Using Boost.Iostreams can make the task easier.

Non-portable gcc solution is:

#include <ext/stdio_filebuf.h>

{
int fd = ...;
__gnu_cxx::stdio_filebuf<char> fd_file_buf{fd, std::ios_base::out | std::ios_base::binary};
std::ostream fd_stream{&fd_file_buf};
// Write into fd_stream.
// ...
// Flushes the stream and closes fd at scope exit.
}

Getting filename (or path) from fstream

No, that is not possible, not at least in the Standard conformant implementation of the library.

The fstream class doesn't store the filename, and doesn't provide any function for retrieving it.

So one way to keep track of this information is to use std::map as:

std::map<std::fstream*, std::string> stream_file_table;

void f()
{
//when you open a file, do this:
std::fstream file("somefile.txt");

stream_file_table[&file] = "somefile.txt"; //store the filename

//..
g(file);
}
void g(std::fstream & file)
{
std::string filename = stream_file_table[&file]; //get the filename
//...
}

Or, simply pass around the filename as well.

How to get file id from std::ofstream

There is no standard way to get a file descriptor from a standard fstream. There may be a platform specific method, depending on your standard library implementation.

If you're using libstdc++ then according to this there may be a filedesc() method on the fstream object that gives you what you want.

Get FILE* from fstream

No, at least not in a portable way.

GCC's libstdc++ has a class called stdio_filebuf that you can use with a stream, and it does allow you to directly get the associated FILE*, but, stdio_filebuf is not a basic_filebuf, and cannot be used with basic_fstream.

C++ std::fstream how to move to a certain line and column of a file

The following function can do just you want:

std::string GetLine(std::istream& fs, long long index)
{
std::string line;
for (size_t i = 0; i <= index; i++)
{
std::getline(fs, line);
}
return line;
}

The above function gets the line at index (index == 0 - 1st line, index == 2 - 3rd line, etc.).

Usage:

#include <iostream>
#include <string>
#include <fstream>

std::string GetLine(std::istream& fs, long long index)
{
std::string line;
for (size_t i = 0; i <= index; i++)
{
std::getline(fs, line);
}
return line;
}

int main()
{
std::ifstream fs("input.txt"); // fstream works too
std::cout << GetLine(fs, 1);
}

input.txt

This is
a
test file

Output:

a


Related Topics



Leave a reply



Submit