Error with std::getline - c++

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.

Related

Function cannot be referenced as it is a deleted function

Hello I am learning C++ from a book and am on a exercise question below
Write a function that takes and returns an istream&. The function should read the stream until it hits end-of-file. The function should print what it reads to the standard output. Reset the stream so that it is valid before returning the stream.
#include "stdafx.h"
#include <iostream>
#include <istream>
#include <string>
#include <string.h>
#include <list>
#include <vector>
#include <fstream>
std::istream ReadFile(std::istream &iStream)
{
std::string word;
while (iStream >> word)
{}
std::cout << "I read value " << word << std::endl;
iStream.setstate(std::ios::goodbit);
return iStream;
}
int _tmain(int argc, _TCHAR* argv[])
{
ReadFile(std::cin);
system("pause");
return 0;
}
The above is my attempt, however I am getting errors at the "return iStream" line.
Error1 error C2280: 'std::basic_istream<char,std::char_traits<char>>::basic_istream(const std::basic_istream<char,std::char_traits<char>> &)' : attempting to reference a deleted function
2 IntelliSense: function "std::basic_istream<_Elem, _Traits>::basic_istream(const std::basic_istream<_Elem, _Traits>::_Myt &) [with _Elem=char, _Traits=std::char_traits<char>]" (declared at line 77 of "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\istream") cannot be referenced -- it is a deleted function
I don't really know what these errors are, I am aware you can delete stuff but I am not onto that topic in the book yet. As far as I know I have not at all touched the istream file... Can someone help me please?
Thanks!
You can’t return an istream by value because it’s not copyable.
Since it’s not copyable the copy constructor has been deleted (to enforce the non-copyability), and that’s the direct technical cause of the diagnostic.
So, instead of
std::istream ReadFile(std::istream &iStream)
… do
std::istream& ReadFile(std::istream& iStream)
In other news, …
Instead of
#include "stdafx.h"
just turn off precompiled headers in the Visual Studio project settings.
This also gives you more standard-conforming behavior for header inclusions.
If you don’t do that, then configure the project so that any warning about skipping an include, yields a hard compilation error.
Instead of
iStream.setstate(std::ios::goodbit);
… do
istream.clear();
Instead of the non-portable Microsoft monstrosity
int _tmain(int argc, _TCHAR* argv[])
just use standard
int main()
or in C++11 trailing return type syntax,
auto main() -> int
Instead of
system("pause");
simply run your program via Ctrl+F5 in Visual Studio. Or, place a breakpoint on the last right brace of main and run in the debugger. Or, run the program from the command line.
The exercise formulation
” should read the stream until it hits end-of-file
is ambiguous, but anyway reading words, as you’re doing, does not faithfully reproduce whitespace in the stream. For a more accurate reproduction of the stream contents you can either read character by character, or (via getline) line by line. Or, you can use a special mechanism for this task, namely outputting the read buffer, which does everything in one little statement.
Finally, you don’t need all those headers. You only need <iostream>, and if you choose to read lines, also <string>. Also, you don’t need the return 0; at the end of main, because that’s the default.
A deleted function is a special function (constructor, destructor, operator) that has been explicitly disabled. If you look carefully at the error you can see that the function is the basic_istream copy-constructor, which is disabled because istreams cannot be copied. You are attempting to copy the istream when you return istream, since your function is declared as returning an istream (rather than e.g. returning a reference to an istream).

implementing function in a class causes error: member reference base type 'ifstream (string)' is not a structure or union

I'm trying to implement a function that reads a column of data from a text file and stores it in a vector, which works. However when I try to implement it inside of a class I'm clearly missing some step. This causes the terminal to output the following message:
Outout for
error: member reference base type
'ifstream (string)' is not a structure or union
...
error: member reference base type
'ifstream (string)' is not a structure or union
while(!file.eof()){
..
error: invalid operands to binary
expression ('ifstream (*)(string)' and 'double')
file >> line;
In my class I try to implement the following function to be used with it's data members:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <fstream>
using namespace std;
class spectData{
public:
vector<double> x, y, z;
vector< int> A;
vector<double> readVector(string){
ifstream file(string);
double line;
vector<double> a;
if(file.fail()){
cout << "-----------------\n";
cout << "Input file error!\n";
}
while(!file.eof()){
file >> line;
a.push_back(line);
}
return a;
};
};
Any hint as to why this wouldn't work inside a function, but would inside main function?
using namespace std;
...
vector<double> readVector(string){
// ~~~~~~^
// missing parameter name
ifstream file(string);
// ~~~~~^
// whoops, type name aka std::string instead of parameter name
What your ifstream file(string); currently does, it declares a function file that takes by value a parameter of the std::string type and returns the std::ifstream instance. Hence the error you get. What you probably meant to do is to supply a path parameter to your file's constructor:
vector<double> readVector(const string& path){
// ~~~~~~~~~~~~~~~~~^
// parameter name
ifstream file(path.c_str());
// ~~~^ ~~~~~~^
//
The issues in this code are numerous, including:
Failing to include <string>. Don't rely on another header to do that for you.
Invalid parameter naming (as in, you have none; remember parameters are Type name).
Building on the mistake from above, ifstream file(string); therefore declares a function called file that takes a string parameter and returns an ifstream (which is impossible, as that class does not support copy construction, but does support move construction, not that it matters here).
Using .eof() as a loop condition, which is nearly always wrong (and this is no exception). Read this for why.
Minor: Reinventing the iterative read operation. std::istream_iterator provides this functionality for you, and should be exploited.
Minor: blanketing this with using namespace std;
For example:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
class spectate
{
public:
std::vector<double> x, y, z;
std::vector< int> A;
std::vector<double> readVector(const std::string& fname)
{
std::vector<double> res;
std::ifstream file(fname);
if(!file)
{
std::cout << "-----------------\n";
std::cout << "Input file error!\n";
}
else
{ // dump the file of doubles into your vector
std::copy(std::istream_iterator<double>(file),
std::istream_iterator<double>(),
std::back_inserter(res));
}
return res;
}
};
Truth be told, you can forego much of that if error reporting is handled by the caller (such as an empty file, vector, etc), at which point that entire member can be reduced to simply:
std::vector<double> readVector(const std::string& fname)
{
std::ifstream file(fname);
return std::vector<double> {
std::istream_iterator<double>(file),
std::istream_iterator<double>() };
}
It somewhat brings into question whether the function is truly even needed at all. The caller could just as easily have done this entirely on their side.
string is a typename that you've pulled in inadvertently via the using namespace std. As a result, file is not what you intended - it is a function taking a std::string and returning an std::ifstream. Avoid using namespace std except in very controlled scopes - definitely not in header files.
#include <vector>
does includes std::string. After using namespace std; std::string becomes type string so you cant use string as variable name because it is a type.
You should write using std::vector; instead of using namespace std;

Confusion about constructors - expected a ';'

Instead of putting my class in the same file as my main function, I'm trying to use a #include. Though, when I do this, I get an error for my constructor. This is my input.cpp file:
#ifndef input
#define input
using namespace std;
#include <string>
#include <iostream>
class input
{
public:
input(int sent)
{
s = sent;
}
void read();
void store(string s);
private:
int s;
};
#endif
This is my main function:
#include <iostream>
#include <string>
using namespace std;
#include "input.cpp"
int main()
{
cout<<"Hello, please enter your input"<<endl;
string sent;
getline(cin, sent);
cout<<sent;
input1 *newinput = new input1("hello");
system("pause");
return 0;
}
The error I'm getting is
"intelliSense expected a ';'"
in the body of my constructor. Though, when I copy / paste the class directly into my main.cpp file, the error goes away. Any idea on what is causing this?
Do no use using namespace in headers
You have input as macro constant and name of class is the same. I afraid it's the root your problem.
Prefer to use constructor initialization lists input(int sent) : s(sent) {}
UPDT
you may need constructor able to accept string as parameter input(const std::string& str1) : str(str1) {} where str is class member to handle string data.
You defined the constructor as having one parameter of type int
input(int sent)
{
s = sent;
}
but try to call it passing as an argument a string literal
input *newinput = new input("hello");
The string literal that has type const char[6] can not be implicitly converted to type int and the class has no other constructor that accepts character arrays as arguments.
EDIT: You changed you original post several times so it is not clear now whether using name input1 in stateent
input1 *newinput = new input1("hello");
is a typo or it is some other type.
Also you have a macro definition with the same name as the class name
#ifndef input
#define input
Change either the macro name or the class name.

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

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

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..."