Is it possible to create an ifstream without a real file - c++

I am using a third party library which needs a ifstream object as input and I have a stringstream object which contains everything they need. Right now, I have to write the content of stringstream to a file and then send a ifstream object to the library. I am wondering if it is possible directly convert stringstream to ifstream in memory so I don't need to write a file on disk? thanks.

I your library is really accepting std::ifstream instead of std::istream, then I found the following hack:
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
void foo(std::ifstream& fs)
{
std::string h;
fs >> h;
std::cout << h << std::endl;
}
int main()
{
std::istringstream s1("hello");
std::ifstream s2;
s2.basic_ios<char>::rdbuf(s1.rdbuf());
foo(s2);
return 0;
}
I am not sure how safe it is, however, so you might investigate the topic further.

Related

Creating a file with variable name in c++

so I want to create a file but the name of it will be dependent on the user input e.g. if the user types "shrek" the file must be named "shrek.txt". Thats what I came up with but it doesn't work.
int main(){
ofstream file;
string name = "abc";
file.open(name + ".txt");
file.close();
}
I guess you are using an old C++ standard. If that's the case, fstream::open won't accept a std::string, only a C string (char*). You can use c_str in your string to obtain a const char* that will be accepted:
int main(){
ofstream file;
string name = "abc";
string file_name = name + ".txt";
file.open(file_name.c_str()); // <- here
file.close();
}
However, it's recommendable to switch to a more modern standard, as your code actually works for C++11 and newer.
Do you have the libraries required? In this case #include fstream. Does the same issue happens to another complier? Check that out. I attempted this myself and your code surely works. Attempt to use my code which I confirm works and see if you have any issues.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
string name;
cin>> name;
ofstream file(name +".txt");
file.close();
}

passing ifstream object to function and use getline() in between

I want to open a file named 1.board by calling a function and use getline function to print it's characters to new line.But this is showing a lot of errors.
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using std::ifstream;
using std::cout;
using std::string;
using std::vector;
void ReadBoardFile(ifstream& search)
{
string line;
search.open("1.board");
while(getline("1.board",line))
{
cout<<line<<"\n";
}
}
int main() {
ifstream fin;
ReadBoardFile(fin);
}
I don't know what i'm doing wrong.I just can't find a perfect and exact answer.
Help,if you can.Thanku!!!!!
So here's your code rewritten so it works.
Two changes, first the first parameter to getline should be the stream you are reading from not the name of a file. I'm guessing that you just weren't concentrating when you wrote that.
Second change, I've moved the stream variable search so that it is local to your ReadBoardFile function. There's no reason in the code you've posted to pass that in as a parameter. You might want to pass the name of the file as a parameter, but I'll leave you to make that change.
void ReadBoardFile()
{
ifstream search("1.board");
string line;
while(getline(search,line))
{
cout<<line<<"\n";
}
}
int main() {
ReadBoardFile();
}

Cast a variable of filtering_istream type to ifstream type?

I am using the filetering_istream type to save the information in a decompressed file while using 'boost/iostreams/filtering_stream.hpp'. But I want to cast it into the ifstream type. It there any way to do it? Great thanks!
The code is as follows:
#include <istream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
int main(){
std::ifstream file("test_data.dat.gz");
boost::iostreams::filtering_istream in;
in.push(boost::iostreams::gzip_decompressor());
in.push(file);
/* add code to convert filtering_istream 'in' into ifstream 'pfile' */
/* It seems that the following code returns a pointer NULL */
// std::ifstream* pfile = in.component<std::ifstream>(1);
return 0;
}
After trying boost::ref and boost::wrapper proposed by zett42, the ifstream really works. The only problem is that it doesn't give the phrases wanted.
In my text of .gz file, I wrote:
THIS IS A DATA FILE!
8 plus 8 is 16
But using the ifstream, I got:
is_open: 1
\213<\373Xtest_data.dat\361\360V"G\307G7OWE.\205\202\234\322b\205\314bC3.\327+>\314$
I am not sure what happened here, and can I do something to recover it?
From the reference of filtering_stream:
filtering_stream derives from std::basic_istream, std::basic_ostream
or std::basic_iostream, depending on its Mode parameter.
So no, you can't cast a filtering_stream directly to an ifstream because there is no inheritance relationship between the two.
What you can do instead, if your filter chain ends with a device that is an ifstream, you can grap that device by calling filtering_stream::component(). For streams this function returns a boost::iostreams::detail::mode_adapter (you can see the type by calling in.component_type(1)).
It's propably not a good idea to depend on an internal boost type (indicated by namespace "detail") which could change with next boost version, so one workaround is to use boost::reference_wrapper instead.
#include <iostream>
#include <istream>
#include <fstream>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/core/ref.hpp>
int main(){
std::ifstream file("test_data.dat.gz");
boost::iostreams::filtering_istream in;
in.push(boost::iostreams::gzip_decompressor());
in.push(boost::ref(file));
if( auto pfile = in.component<boost::reference_wrapper<std::ifstream>>( 1 ) )
{
std::ifstream& rfile = *pfile;
std::cout << "is_open: " << rfile.is_open() << "\n";
}
}

Parsing a Very Simply Config File

I am writing a OBDII reading library / application in C++. Data is retrieved from the car's computer by sending a simple string command, then passing the result through a function specific to each parameter.
I would like to read a config file of all the commands I want, something like this perhaps:
Name, Command, function
Engine RPM, 010C, ((256*A)+B)/4
Speed, 010D, A
Basically, very simple, all data needs to just be read in as a string. Can anyone recommend a good simple library for this? My target is g++ and/ or Clang on Linux if that matters.
You could use std::ifstream to read line by line, and boost::split to split the line by ,.
Sample code:
You could check tokens size for sanity checks of file loaded.
#include <fstream>
#include <vector>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
int main(int argc, char* argv[]) {
std::ifstream ifs("e:\\save.txt");
std::string line;
std::vector<std::string> tokens;
while (std::getline(ifs, line)) {
boost::split(tokens, line, boost::is_any_of(","));
if (line.empty())
continue;
for (const auto& t : tokens) {
std::cout << t << std::endl;
}
}
return 0;
}
You could also use String Toolkit Library if you don't want to implemented. Docs

C ++ ifstream I/O?

I'm experimenting with C++ file I/O, specifically fstream. I wrote the following bit of code and as of right now it is telling me that there is no getline member function. I have been told (and insisted still) that there is a member function getline. Anybody know how to use the getline member function for fstream? Or perhaps another way of getting one line at a time from a file? I'm taking in two file arguments on the command line with unique file extensions.
./fileIO foo.code foo.encode
#include <fstream>
#include <iostream>
#include <queue>
#include <iomanip>
#include <map>
#include <string>
#include <cassert>
using namespace std;
int main( int argc, char *argv[] )
{
// convert the C-style command line parameter to a C++-style string,
// so that we can do concatenation on it
assert( argc == 2 );
const string foo = argv[1];
string line;string codeFileName = foo + ".code";
ifstream codeFile( codeFileName.c_str(), ios::in );
if( codeFile.is_open())
{
getline(codeFileName, line);
cout << line << endl;
}
else cout << "Unable to open file" << endl;
return 0;
}
getline(codeFileName, line);
Should be
getline(codeFile, line);
You're passing in the file name, not the stream.
By the way, the getline you're using is a free function, not a member function. In fact, one should avoid the member function getline. It's much harder to use, and harkens back to a day when there was no string in the standard library.
Typo
getline(codeFileName, line);
should be
getline(codeFile, line);
I guess the lesson is you have to learn how to interpret compiler error messages. We all make certain kinds of mistakes and learn the compiler errors they tend to generate.