How to pass cin or ifstream object as argument function - c++

I though this would work since ifstream inherits from istream
string getFileContents(istream& file_contents)
{
string result;
string line;
while (getline(file_contents, line))
result += line + "\n";
return result;
}
then I want to call this function like so:
ifstream file_input;
getFileContents(file_input);
...
getFileContents(cin);
but I get this error in visual studio:
'getFileContents' : cannot convert parameter 1 from std::istream to std::ifstream &

It should work; are you sure you didn't leave around a wrong prototype that has a parameter of type ifstream & instead of istream &?

Related

What is wrong with my vector declaration in c++?

I'm having trouble declaring a vector of class objects. The class I'm trying to reference is in a header file and its constructor calls for an array of 6 strings.
string Data[6];
vector<Gamer> fileOut;
void split(string input)
{
stringstream ss(input);
int count = 0;
while (ss.good()) {
string substr;
getline(ss, substr, ' ');
Data[count] = substr;
count++;
}
}
void readGamerfile()
{
ifstream myfile;
myfile.open("gamers.txt");
string line;
while (getline(myfile, line)) {
split(line);
fileOut.push_back(new Gamer(Data));
}
}
Above is my code and I'm not sure why when I declare the variable fileOut I get an error saying:
identifier "gamer" is undefined
I'm using visual studio code and I'm not really sure whats going on because I believe it should work. Any help would be greatly appreciated.
Since your vector is declared as follows
vector<Gamer> fileOut;
you do not need new here
fileOut.push_back(Gamer(Data));
or even
fileOut.emplace_back(Data);
Also make sure you include whatever header is required for the definition of Gamer
#include "Gamer.h"
If Gamer is a structure the declaration should be vector<struct Gamer> or if it is an object then vector<className>.

fstream library, trying to create a file with variable name (c++)

i am trying to create a file whose name is tied to a string type variable, however when i try to run it, i get this error --[Error] no match for call to '(std::ofstream {aka std::basic_ofstream}) (const char*)'
Here is the code:
void Crear()
{
string nombre;
ofstream output;
ifstream input;
cout << "Deme el nombre de su archivo: ";
cin.ignore();
getline(cin, nombre);
//this is where the error happens
output(nombre.c_str());
}
In this statement:
output(nombre.c_str());
The compiler thinks that output is a "callable" but std::fstream didn't overload call operator. So you get compile-time error.
To fix it; you either call the member open:
output.open(nomber); // directly because the new standard allows strings for fstream::open
or when initializing output:
std::ofstream output(nombere); // (contructor of ofstream that takes std::string) or
std::ofstream output(nombere.c_str()); // ctor that takes const char*

How to assign istringstream and ifstream to an istream variable?

I want to have a variable of type istream which can hold either the contents of a file or a string. The idea is that if no file was specified, the variable of type istream would be assigned with a string.
std::ifstream file(this->_path)
and
std::istringstream iss(stringSomething);
to
std::istream is
I've tried just assigning them to the istream variable like I would with other objects that inherit from the same base class, but that didn't work.
How to assign istringstream and ifstream to an istream variable?
Base class pointers can point to derived class data. std::istringstream and std::ifstream both derived from std::istream, so we can do:
//Note that std::unique_ptr is better that raw pointers
std::unique_ptr<std::istream> stream;
//stream holds a file stream
stream = std::make_unique<std::ifstream>(std::ifstream{ this->_path });
//stream holds a string
stream = std::make_unique<std::istringstream>(std::istringstream{});
Now you just have to extract the content using
std::string s;
(*stream) >> s;
You can't assign to a std::istream but you can bind to a reference like this:
#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
std::istringstream test_data(R"~(
some test data here
instead of in an external
file.
)~");
int main(int, char* argv[])
{
// if we have a parameter use it
std::string filename = argv[1] ? argv[1] : "";
std::ifstream ifs;
// try to open a file if we have a filename
if(!filename.empty())
ifs.open(filename);
// This will ONLY fail if we tried to open a file
// because the filename was not empty
if(!ifs)
{
std::cerr << "Error opening file: " << filename << '\n';
return EXIT_FAILURE;
}
// if we have an open file bind to it else bind to test_data
std::istream& is = ifs.is_open() ? static_cast<std::istream&>(ifs) : test_data;
// use is here
for(std::string word; is >> word;)
{
std::reverse(word.begin(), word.end());
std::cout << word << '\n';
}
}
Take a page out of the standard library: don't assign a value; assign a reference. That's probably what you want anyway.
std::istringstream iss(stringSomething);
std::istream& input(iss);
Because streams carry a lot of state, copying them is fraught with semantic questions. Consider for example what tellg should report in the copy after the original calls seekg. References by contrast answer the question transparently.
In C++, you cannot assign an object of type Child to a variable of type Parent, even if Child inherits from Parent. You can assign a pointer of type Child to a pointer of type Parent, however. You may want to consider dynamically allocating the objects.
In C++
std::istream is;
is an actual object, assigning to it will invoke the copy assignment operator which will copy the subobject of iss which is a std::istream into is and slice it. The example linked by LogicStuff will show that you need to assign a reference or pointer to iss like so:
std::istream &is_ref = iss;
The difference between values, references and pointers is fundamental to C++, I would advise getting a strong grasp of them.
std::istream can be constructed from a std::streambuf (basically the device that produces or consumes characters). All i/ostream objects have an associated std::streambuf and can be shared.
std::ifstream file(this->_path);
std::istringstream iss("str in gSo met hing");
std::istream A(iss.rdbuf()); // shares the same buffer device with iss
std::string str;
//////////////
while(A >> str) std::cout << str << " | "; //read everything from stream (~> iss)
std::cout << std::endl;
A = std::move(file);
while(A >> str) std::cout << str << " | "; //read from file, using same stream (~> file)

declaring input stream

I have a C++ code with
ifstream myfile;
myfile.open("input");
and then has commands like:
myfile.getline(inp,256);
Question: How can I modify myfile.open("input") so that myfile is associated with cin instead of "input"?
I don't want to change all myfile.getline commands to cin.getline.
Declaring myfile=cin does not compile.
Use an istream& reference instead:
std::istream& myfile(std::cin);
Separate it out into a function and take the std::istream& as an argument. Then you can execute on both std::cin and myfile as you wish.
You can put your code into a function that takes a reference to a std::istream, e.g.
void process_data( std::istream & istr )
{ ... }
Then you can call this function both with any std::ifstream and with std::cin:
std::ifstream myfile;
...
process_data( myfile );
process_data( std::cin );
If you insist in using an std::ifstream you can replace the std::streambuf of the base std::istream (std::ifstream overloads rdbuf() so you can't use it directly):
std::ifstream file;
if (use_cin) {
file.std::istream::rdbuf(std::cin.rdbuf());
}

No matching constructor for initialisation of 'ifstream'

I am geting an an error in the following code it worked fine in visual studio but once i have moved it over to Xcode that uses gcc to compile get this error No matching constructor for initialisation of 'ifstream' i have looked at adding this as a reference rather than a copy as suggested on this site but it still came up with the error.
void getAndSetTextData::GetBannedList(string fileName)
{
bannedWordCount = 0;
ifstream inFile(fileName);
while(inFile >> currentWord)
{
bannedWords.push_back(currentWord);
bannedWords[bannedWordCount++] = currentWord;
}
inFile.close();
}
Any help would be appreciated.
ifstream constructor accepts a const char* as the filename (prior C++11):
ifstream inFile(fileName.c_str());
An additional constructor that accepts a const std::string& as the filename was added in C++11.
Minor point: consider changing argument string fileName to const string& fileName to avoid unnecessary copy of fileName.
first you should check that weather the file is opened or not. for example if you dont have permission to access the file or if you are opening a file in write mode when there is no enough disk space, etc...
so
ifstream inFile(fileName);
if( ! inFile )
return;
while(inFile >> currentWord)
and about your question, are you including the fstream?