Passing a string argument to ifstream - c++

I'm trying to pass a string argument to a function from the main function and then passing this received string argument to ifstream constructor. I'm able to receive this string in the function, but when I pass this argument to ifstream, I get a error message:
no matching function for call to ‘std::basic_ifstream::basic_ifstream(const string&)’
std::ifstream file(fileName);
Here is my code:
int** read_CSV(std::string const& fileName)
{
//cout<<fileName<<"\n";//this works
std::ifstream file(fileName);//problem
//Rest of logic
}
The main function:
int main()
{
int** inputMatrix1 = read_CSV("inputData4_80-20_100x32.csv");
return 0;
}
The variable fileName is creating the problem. If I pass it as it is, it gives the error. But instead, if I explicitly mention the name of the file using string rather than the variable, the code works fine. Can someone explain what exactly is the problem here and how I can solve it?

Okay, so the problem was that I was trying to compile without C++11 standard using just g++ "NameOfFile.cpp". There are 2 possible solutions to the problem, from the comment section, and they are as follows:
Using -std=c++11 when giving the command for compilation. The resultant compilation command would look as follows:
g++ -std=c++11 "NameOfFile.cpp"
Another solution, as pointed out by #Peter, is to use c_str() at the end of the string object, since the ifstream doesn't accept strings as an argument before c++11, so c_str() is used for explicitly converting to a compatible format.
Here's the modified code line for the second solution:
std::ifstream file(fileName.c_str());
Thanks to #Peter and #Holt for their inputs.

Related

ifstream no conversion from char to char exists error

int main()
{
char buffer[1024];
ifstream dataFile ("./data.dat");
while(buffer)
{
localHouse->location = dataFile.getline(buffer, 1024);
}
}
This throws the error: No suitable converion function from "std::basic_istream<char, std::char_traits<char>>" to "char" exists.
It continues to throw this error if I use a pointer to buffer instead. as far as I can tell I'm using it exactly as seen in the example here.
There's another example on stackoverflow here
That shows similar usage but I can't get it to work, and it's really causing me to tear my hair out over an error that seems to say it can't convert from the char to char. >.<
getline's return value is the istream object which I guess it's not something that you want to assign to localHouse->location.
getline reads a line of your file into buffer variable that you have provided as the first parameter.

Using std::string Datatype in std::vector's Constructor

This isn't so much a specific question about RapidXML convention as it is a question about using a std::vector's constructor.
In all examples that I have found of others using RapidXML, everyone always reads data into a vector of char's using the std::vector's constructor like so:
vector<char> buffer((istreambuf_iterator<char>(theFile)), istreambuf_iterator<char>());
There must be a reason for this because when I try to change it to a vector of std::string's I get a screen full of errors with this being the first error:
error: invalid conversion from ‘void*’ to ‘std::istreambuf_iterator<std::basic_string<char> >::streambuf_type* {aka std::basic_streambuf<std::basic_string<char>, std::char_traits<std::basic_string<char> > >*}’
Is there a way to use std::string and if not why?
What are you trying to do?
Do you want the contents of the file in a single string? If so, then
string buffer((istreambuf_iterator<char>(theFile)), istreambuf_iterator<char>());
should do it.
On the other hand, if you want a vector of strings, with each string containing a single line from the file, you'll have to write a loop like this (untested code):
vector <string> lines;
for (string aLine; std::getline(theFile, aLine) ; )
lines.push_back(aLine);

c++: Reading a file line by line

I'm wondering if there's a C++ way of opening a file and reading the input line by line.
I encountered the following code that accomplishes the task:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream myfile;
myfile.open ("example.txt");
return 0;
}
I'm encouraged to not use any C functions or commands.
The thing is, my "example.txt" is in the form of a string, and using str.c_str() is a C function, so I guess I have two ways to solve the issue.
Is there another way to read input from a file line by line? Perhaps using something that will accept a string as a parameter for the filepath? Is there a C++ way of doing things? :)
Or, is there another way to convert the string in to a const char *, which is what the myfile.open() function needs?
Many thanks in advance!
EDIT: My lack of practivity and research led me to think c_str() was a C function, and it isn't. My apologies. Since it isn't I have found my answer.
C++11's fstream constructor accepts string. In most cases, you want to use fstream's constructor, rather than .open() - you save one line and one function call.
For reading the file line-by-line, you should use std::getline().
Also note that string::c_str() is still C++ function, not C one, as well as fstream's constructor taking const char *. Most of (if not all, I'm not 100% sure) C standard library function are also included in C++ standard.
Since the issue about str.c_str() is already answered, I'm just gonna add a bit about getting inputs line by line. for example, you wanna take 2 ints input per line, extract them, and put it into a vector.
fstream fs(filename.c_str(), ios_base::in);
string line;
stringstream ss;
int a,b;
vector<int> d;
int numlines;
int i;
for (i = 0; getline(fs, line); i++) {
for (ss.str(line); ss >> a >> b; d.push_back(a), d.push_back(b)) {}
ss.clear();
}
numlines = i;
Hope you get the idea of using getline() and fstream()
It's going to look very similar. You'll want an ifstream instead of an ofstream, you'll want the >> operator, and assuming your file has more than one line, you'll need a loop and the ifstream::feof() function.

Variables not equivalent fstream vs. declaration

Basically I'm reading the contents of a file using fstream then converting it to const char* type. I'm supplying this to Lua, and Lua will do something with this. This however does not work. What does work is if I do:
const char* data = "print('Hello world')";
luaL_pushstring(L, data);
luaL_setglobal(L, "z");
They both are in the type const char* type and they are both the same string (e.g. I compared the two lengths). Except one works, and the other. I'm baffled. Any help here? Here is the code:
std::string line,text;
std::ifstream in("test.txt");
while(std::getline(in, line))
{
text += line;
}
const char* data = text.c_str();
luaL_pushstring(L, data);
luaL_setglobal(L, "z");
Here is the Lua code:
loadstring(z)()
To diagnose this, you probably want to know more about what Lua thought. I'd write the Lua side as assert(loadstring(s))() instead. If loadstring fails, your current code at best prints an error from the attempt to call nil. With the assert() in the sequence, the call to nil will be replaced by a more informative error about what went wrong.
Don't you have to set the global before you push the value? Anyways, what's up, Camoy :P

Pass path to file / filename as argument to a function that prints the file to screen in C++

As the title says, is there any way to pass the path to the file / filename to open as an argument in the function?
I've written a short code for printing a .txt-file to the screen in C++, but instead of having all the code in the main(), I'd rather have it as an own function that I can call with the filename of the file to open as the only input argument.
Basically the beginning of the function would look like
void printFileToScreen()
{
ifstream fin;
char c;
fin.open("FILE_TO_OPEN.txt", ios::in);
blablabla
}
Now is there any way to pass "FILE_TO_OPEN.txt" when I call the function?
I've tried
void printFileToScreen(string str)
{
ifstream fin;
char c;
fin.open(str, ios::in);
blablabla
}
where I call the function like printFileToScreen("FILENAME.txt"), but with no luck, so I'm not sure how to do this.
Hope anyone can help :)
Unfortunately, the iostream functions deal with const char* types rather than with std::string (the iostream functions were developed independently of the STL). You instead could use std::string::c_str() to obtain a const char*:
fin.open(str.c_str(), ios::in);
As a general design rule, I would not pass the file name to the called function. I would pass the already opened std::istream object to read from. This allows you to do the job of printing in a function, and to do the job of opening the file and dealing with non-existent files in another. This has the bonus of being able to pass std::cin to your function!
Try changing your function to look like this :
void printFileToScreen(const string &str);
//If you pass a const char*, a string will be constructed
or this :
void printFileToScreen(const char *);
The function you wrote expects an instance of std::string to be passed by value.
Never mind, after some more trying and failing I found out that I needed to pass a char pointer, and not a string. :)
Of course you can pass the filename as a function parameter. If in doubt, pass a "const char*" rather than a string. I should work.