How do I use fstream (specifically ofstream) through a functions parameters - c++

Hi I'm a c++ beginner and this is one of my assignments and I'm a bit stuck. This isn't my entire code it's just a snippet of what I need help with. What I'm trying to do is have one function dedicated to exporting everything with that function into a text file which is called results.txt. So the line "does this work" should show up when I open the file, but when I run the file I get errors like
"Error C2065: 'out' : undeclared identifier"
"Error C2275: 'std::ofstream' : illegal use of this type as an expression"
"IntelliSense: type name is not allowed"
"IntelliSense: identifier "out" is undefined"
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
//prototypes
void output(ofstream& out);
int main()
{
output(ofstream& out);
ifstream in;
in.open("inven.txt");
ofstream out;
out.open("results.txt");
return 0;
}
void output(ofstream& out)
{
out << "does this work?" << endl;
}
Right now it's really late and I'm just blanking out on what I'm doing wrong.

First of all, this is fine:
void output(ofstream& out)
{
out << "does this work?" << endl;
}
However, this is not:
int main()
{
output(ofstream& out); // what is out?
ifstream in;
in.open("inven.txt");
ofstream out;
out.open("results.txt");
return 0;
}
This is the first error you get: "Error C2065: 'out' : undeclared identifier", because the compiler doesn't know about out yet.
In the second fragment you want to call output with a specific ostream&. Instead of calling a function, you're giving a function declaration, which isn't allowed in this context. You have to call it with the given ostream&:
int main()
{
ifstream in;
in.open("inven.txt");
ofstream out;
out.open("results.txt");
output(out); // note the missing ostream&
return 0;
}
In this case you call output with out as parameter.

Since you described yourself as a begginer, I'll answer accordingly and hopefully in a educational manner. Here is what is happening: Think of fstream, ofstream and ifstream as smart variable types (even if you know what classes are, think like that for the sake of logical clarity). Like any other variable, you have to declare it before you use. After it is declared, that variable can hold a compatible value. The fstream variable types is for holding files. All variations of it hold the same thing, just what they do that is different.
You use the variable to open a file, use it in your program, then close.
Hope this helps

Related

C++11 error no match for call to Ifstream outside main

I'm brand new to c++, trying to learn it on my own.
I've found several questions related to this but none of them have really answered it. I've enabled c++11 so ifstream should accept a std::string as far as I can tell. I've also tried this in Visual Studio, CLion, and Eclipse Neon with the exact same results.
I've also checked the value of __cplusplus at runtime and I know it is set to 201103, which is required for the overloading of the constructor.
Essentially if I use std::ifstream in the main function using a std::string I have no problems. On the other hand if I try to pass it to a another class that in another file I receive this error in Eclipse and Clion:
"error: no match for call to '(std::ifstream {aka std::basic_ifstream}) (std::__cxx11::string&)' infile(filename);"
And this error in Visual Studio:
"error C2064: term does not evaluate to a function taking 1 arguments"
Both errors point to the same line as indicated in the code block below. I would like to know what I'm doing wrong as I'd like to use ifstream inside of the class.
// main.cpp
#include test.h
int main() {
std::string name("test.txt");
TestClass test (name);
std::ifstream testfile(name);
return 0;
}
// test.h
#include <fstream>
class TestClass{
std::ifstream infile;
public:
TestClass(std::string filename); // have also tried with std::string& filename
}
// test.cpp
TestClass::TestClass(std::string filename){ // again have tried using string&
infile(filename); /** ERROR **/
}
std::ifstream doesn't provide a operator()(std::string) overload. Hence
infile(filename);
in the constructor body fails to compile.
There is a constructor taking a const std::string& though, that can be used in your classes member initializer list:
TestClass::TestClass(std::string filename) : infile(filename) {
// Omit that completely: infile(filename); /** ERROR **/
}

Error with std::getline

So this is the code:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
void print_file(const ifstream& dat_in)
{
if(!dat_in.is_open())
throw ios_base::failure("file not open");
string buffer;
while(getline(dat_in, buffer)); //error here
}
int main()
{
ifstream dat_in("name_of_the_file.txt");
try{
print_file(dat_in);
}
catch(ios_base::failure exc){
cout << exc.what() << endl;
}
}
And I get an error that no instance of overloaded function std::getline matches the argument list.
I did this line of code a thousand of times, what is the problem now ...
3 IntelliSense: no instance of overloaded function "getline" matches the argument list
argument types are: (const std::ifstream, std::string)
Error 1 error C2665: 'std::getline' : none of the 2 overloads could convert all the argument types
The culprit is the const:
void print_file(const std::ifstream& dat_in)
// ^^^^^
Of course the std::ifstream's state is changed when reading data from it, thus it cannot be const in that context. You should simply change your function signature to
void print_file(std::ifstream& dat_in)
to get this working.
BTW the function name print_file is pretty confusing for a function that actually reads from a file.
the problem is here
void print_file(const ifstream& dat_in)
getline necessarily changes the stream that is passed-in. So change the above to (remove const)
void print_file(ifstream& dat_in)
Your code is passing a reference to a const ifstream parameter as the first parameter to std::getline(). Since std::getline() modifies its input stream parameter, it cannot have a const reference as the first parameter.
The error message from the compiler included a list of all the parameters, and it should've indicated that the first parameter is a const reference.
As a rule of thumb, pass and return all streams types as reference, neither const or by-value. Remember that const refers to the object, not the file and the object has many things that could change even if the file is a read-only file.

constructor opens a file with a given filename c++

In my code below errors occur and the program will not run, I am required to make a Constructor that must open the file with the given filename. If the filename does not exist then it Prints an error message and terminates the program.
Below is the code that I have done so far in C++:
#include "ReadWords.h"
#include <iostream>
#include <cstdlib>
using namespace std;
ReadWords::ReadWords(const char filename[])
{
wordfile.open(filename);
if (!wordfile)
{
cout << "cannot make " << filename << endl;
exit(1);
}
}
void ReadWords::close()
{
wordfile.close();
}
Why dont you try including fstream to the top of your file and see if that works
I suppose wordfile is of type std::fstream. If your ReadWords.h #includes <fstream>, it should work (compiles and works as expected).
By the way, it's a bad practice to use using namespace std;.
Also, since you use C++, take a look at std::string. It's safer than using plain char* or char[].

expected constructor, destructor, or type conversion before ‘(’ token

Compiling polygone.h and polygone.cc gives error:
polygone.cc:5:19: error: expected constructor, destructor, or type conversion before ‘(’ token
Code:
//polygone.h
# if !defined(__POLYGONE_H__)
# define __POLYGONE_H__
# include <iostream>
class Polygone {
public:
Polygone(){};
Polygone(std::string fichier);
};
# endif
and
//polygone.cc
# include <iostream>
# include <fstream>
# include "polygone.h"
Polygone::Polygone(string nom)
{
std::ifstream fichier (nom, ios::in);
std::string line;
if (fichier.is_open())
{
while ( fichier.good() )
{
getline (fichier, line);
std::cout << line << std::endl;
}
}
else
{
std::cerr << "Erreur a l'ouverture du fichier" << std::endl;
}
}
//ifstream fich1 (argv[1], ios::in);
My guess is that the compiler is not recognising Polygone::Polygone(string nom) as a constructor, but, if this actually is the case, I have no idea why.
Any help?
This is not only a 'newbie' scenario. I just ran across this compiler message (GCC 5.4) when refactoring a class to remove some constructor parameters. I forgot to update both the declaration and definition, and the compiler spit out this unintuitive error.
The bottom line seems to be this: If the compiler can't match the definition's signature to the declaration's signature it thinks the definition is not a constructor and then doesn't know how to parse the code and displays this error. Which is also what happened for the OP: std::string is not the same type as string so the declaration's signature differed from the definition's and this message was spit out.
As a side note, it would be nice if the compiler looked for almost-matching constructor signatures and upon finding one suggested that the parameters didn't match rather than giving this message.
The first constructor in the header should not end with a semicolon. #include <string> is missing in the header. string is not qualified with std:: in the .cpp file. Those are all simple syntax errors. More importantly: you are not using references, when you should. Also the way you use the ifstream is broken. I suggest learning C++ before trying to use it.
Let's fix this up:
//polygone.h
# if !defined(__POLYGONE_H__)
# define __POLYGONE_H__
#include <iostream>
#include <string>
class Polygone {
public:
// declarations have to end with a semicolon, definitions do not
Polygone(){} // why would we needs this?
Polygone(const std::string& fichier);
};
# endif
and
//polygone.cc
// no need to include things twice
#include "polygone.h"
#include <fstream>
Polygone::Polygone(const std::string& nom)
{
std::ifstream fichier (nom, ios::in);
if (fichier.is_open())
{
// keep the scope as tiny as possible
std::string line;
// getline returns the stream and streams convert to booleans
while ( std::getline(fichier, line) )
{
std::cout << line << std::endl;
}
}
else
{
std::cerr << "Erreur a l'ouverture du fichier" << std::endl;
}
}
You are missing the std namespace reference in the cc file. You should also call nom.c_str() because there is no implicit conversion from std::string to const char * expected by ifstream's constructor.
Polygone::Polygone(std::string nom) {
std::ifstream fichier (nom.c_str(), std::ifstream::in);
// ...
}
You need the return type, for example "void Polygon..."

write to ostream inside of function with c++

consider the following function:
void writer(ofstream &output) {
output << "a string to write" << endl;
}
but when i try to call this, i get an error that '<<' is not defined. how can I fix this?
Add #include <fstream> or change ofstream to ostream
Most likely you lack an include, so that ofstream is only forward declared.