No matching constructor for initialisation of 'ifstream' - c++

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?

Related

Can I use a member variable of type ofstream initialized in the class constructor?

I'm having issues declaring a constructor of an inherited class.
class Report{
public:
string fileName;
std::ofstream outputFile;
Report(string fileName, ofstream outputFile) {
fileName = fileName;
outputFile = outputFile; //<-- error here
}
void returnFile(string, ofstream);
void Report::returnFile(string name, ofstream file){
file.open(name);
}
};
class financialReport: public Report{
public:
void electorateHappenings();
void electorialImpact();
double finances();
void writetoFile();
financialReport(string fileName, ofstream outputFile)
:Report(fileName, outputFile) { } //<-- error here
};
the error occurs on the 3rd last line :Report(fileName, outputFile).
This line produces the error:
function "std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const
std::basic_ofstream<_CharT, _Traits> &) [with _CharT=char,
_Traits=std::char_traits<char>]" (declared at line 848 of
"C:\MinGW\lib\gcc\mingw32\9.2.0\include\c++\fstream") cannot be referenced
-- it is a deleted function
Is it not possible to create a constructor including ofstream?
The error also occurs on line 9 with outputFile = outputFile.
Thank you.
You can't pass it by copy, you can't copy one, but you can pass it by reference and initialize it in the initializer list of the class:
Demo
class Report {
public:
string fileName;
std::ofstream &outputFile; //reference here
// reference parameter, and initializer list
Report(string fileName, ofstream &outputFile) : outputFile(outputFile) {
fileName = fileName;
}
//...
};
Do the same in financialReport:
financialReport(string fileName, ofstream& outputFile) : Report(fileName, outputFile) {}
^
Note that this is a solution to the problem posed in the question, as normal, but in a more deep analysis, though you don't go in detail about what you want to achieve, I wouldn't go so far as to say it's a wrong approach, but odds are you can structure your program in a better way.
Yes, you can, but the error is telling you that you cannot copy an object of std::ofstream.
Depending on what you want to do, there are two ways to handle it.
Pass the ownership of std::ofstream to your newly created object:
Report(string fileName, ofstream outputFile) :
fileName{std::move(outputFile)},
outputFile{std::move(outputFile)}
{
}
//creation of object:
std::ofstream ofs {"filename.txt"};
Report report {"filename.txt", std::move(ofs)};
//ofs is empty here, it's whole content has been transferred to report object
Pass a reference to existing std::ofstream object:
class Report{
public:
string fileName;
std::ofstream& outputFile;
Report(string fileName, ofstream& outputFile) :
fileName{std::move(outputFile)},
outputFile{outputFile}
{
}
//creation of object:
std::ofstream ofs {"filename.txt}";
Report report {"filename.txt", ofs};
//you can use ofs from both here and from inside of report, but
//you have to ensure that ofs lives as long as report will use it or else you will enter Undefined Behaviour land
Note: If you want to have the same names for class members and for constructor arguments, you need to use member initializer list, like I did. If you decide to use references, you are required to use it as well.

undefined reference to `std::ofstream::open(const std::string&, std::_Ios_Openmode)` [duplicate]

This is the part of the code with an error:
std::vector<int> loadNumbersFromFile(std::string name)
{
std::vector<int> numbers;
std::ifstream file;
file.open(name); // the error is here
if(!file) {
std::cout << "\nError\n\n";
exit(EXIT_FAILURE);
}
int current;
while(file >> current) {
numbers.push_back(current);
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return numbers;
}
And well, I kind of have no idea what is going on. The whole thing compiles properly in VS. However I need to compile this with dev cpp.
I commented out the line throwing errors in the code above. The errors are:
no matching function for call 'std::basic_ifstream<char>::open(std::string&)
no matching function for call 'std::basic_ofstream<char>::open(std::string&)
In different parts of code I get errors like numeric_limits is not a member of std, or max() has not been declared, although they exist in iostream class and everything works in VS.
Why am I getting this error?
Change to:
file.open(name.c_str());
or just use the constructor as there is no reason to separate construction and open:
std::ifstream file(name.c_str());
Support for std::string argument was added in c++11.
As loadNumbersFromFile() does not modify its argument pass by std::string const& to document that fact and avoid unnecessary copy.

No matching function - ifstream open()

This is the part of the code with an error:
std::vector<int> loadNumbersFromFile(std::string name)
{
std::vector<int> numbers;
std::ifstream file;
file.open(name); // the error is here
if(!file) {
std::cout << "\nError\n\n";
exit(EXIT_FAILURE);
}
int current;
while(file >> current) {
numbers.push_back(current);
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return numbers;
}
And well, I kind of have no idea what is going on. The whole thing compiles properly in VS. However I need to compile this with dev cpp.
I commented out the line throwing errors in the code above. The errors are:
no matching function for call 'std::basic_ifstream<char>::open(std::string&)
no matching function for call 'std::basic_ofstream<char>::open(std::string&)
In different parts of code I get errors like numeric_limits is not a member of std, or max() has not been declared, although they exist in iostream class and everything works in VS.
Why am I getting this error?
Change to:
file.open(name.c_str());
or just use the constructor as there is no reason to separate construction and open:
std::ifstream file(name.c_str());
Support for std::string argument was added in c++11.
As loadNumbersFromFile() does not modify its argument pass by std::string const& to document that fact and avoid unnecessary copy.

Why can't I copy executables like this?

Using C++'s <fstream>, it's pretty easy to copy a text file:
#include <fstream>
int main() {
std::ifstream file("file.txt");
std::ofstream new_file("new_file.txt");
std::string contents;
// Store file contents in string:
std::getline(file, contents);
new_file << contents; // Write contents to file
return 0;
}
But when you do the same for an executable file, the output executable doesn't actually work. Maybe std::string doesn't support the encoding?
I was hoping that I could do something like the following, but the file object is a pointer and I'm not able to dereference it (running the following code creates new_file.exe which actually just contains the memory address of something):
std::ifstream file("file.exe");
std::ofstream new_file("new_file.exe");
new_file << file;
I would like to know how to do this because I think it would be essential in a LAN file-sharing application. I'm sure there are higher level APIs for sending files with sockets, but I want to know how such APIs actually work.
Can I extract, store, and write a file bit-by-bit, so there's no discrepancy between the input and output file? Thanks for your help, it's much appreciated.
Not sure why ildjarn made it a comment, but to make it an answer (if he posts an answer, I will delete this). Basically, you need to use unformatted reading and writing. getline formats the data.
int main()
{
std::ifstream in("file.exe", std::ios::binary);
std::ofstream out("new_file.exe", std::ios::binary);
out << in.rdbuf();
}
Technically, operator<< is for formatted data, except when use it like the above.
In very basic terms:
using namespace std;
int main() {
ifstream file("file.txt", ios::in | ios::binary );
ofstream new_file("new_file.txt", ios::out | ios::binary);
char c;
while( file.get(c) ) new_file.put(c);
return 0;
}
Although, you'd be better off making a char buffer and using ifstream::read / ofstream::write to read and write chunks at a time.

C++ Why won't my sample program create the output file?

I'm writing a small/beta testing program that will be put to use in my much bigger program for a project. It requests the user for an input file name (IE data.txt) and creates an output file named filename.out (IE data.out). I've tried a simple outFile << "text here"; to try it out but it doesn't create output file. I'm sure I'm messing something simple here but I can't figure out what.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
//Global variables
ifstream inFile;
ofstream outFile;
void main()
{
// Requests user for input filename
string inputFile;
cout << "Enter File Name: ";
cin >> inputFile;
string outputFile = inputFile.substr(0, inputFile.find_last_of('.')) + ".out";
// Opens both inputFile and outputFile
inFile.open(inputFile.c_str(), ios::in);
outFile.open(outputFile.c_str(), ios::in);
// Checks for input file
if (!inFile)
{
cout << "Unable to open file" << endl;
exit(1);
}
outFile << "Hello world!";
inFile.close();
outFile.close();
}
Because you're trying to open the file for reading:
outFile.open(outputFile.c_str(), ios::in);
Use ios::out instead.
Why did you make these streams global variables rather than local ones? In C++, it's generally preferred to construct objects as late as possible. If you do this, you have all information available to open the streams right in the constructor, which can take the same arguments as the open() member function.
One difference between std::ifstream and std::ofstream is that their open() member functions and constructors apply a different default opening mode. It's in for std::ifstream and out for std::ofstream. You can always override these, but that would somewhat defeat the reason for using those streams in the first place. You could use std::fstream, too. For that you would always have to supply the opening modes. If you're using std::ifstream and std::ofstream, just skip the opening modes. Here's how this is looks when using the constructors instead of the open() member functions (it looks pretty much the same with the latter):
std::ifstream inFile(inputFile.c_str());
std::ofstream outFile(outputFile.c_str());
It's int main(), even if some compilers allow void.
I have strong objections to using directives. But these objections are not as widely shared as the other opinions listed in this answer.