It's been a long time since I've done any C++. What's wrong with this code?
#include <iostream>
#include <fstream>
using namespace std;
main()
{
ifstream& ifs("foo.txt");
}
Gives:
$ g++ foo.cc
foo.cc: In function ‘int main()’:
foo.cc:7:25: error: invalid initialization of non-const reference of type ‘std::ifstream& {aka std::basic_ifstream<char>&}’ from an rvalue of type ‘const char*’
ifstream& ifs("foo.txt");
You used a & when you should not have done.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream ifs("foo.txt");
}
Passing values by reference isn't done in the variable declaration, but instead in the parameter list of the function using the ifstream object. For example, your function main might look like this:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream ifs("foo.txt");
myFunction(ifs);
}
and your called function should look like this:
void myFunction(std::ifstream& in_stream)
{
// ...
}
If you need the C++11 reference type (which I doubt, but maybe), try this:
ifstream ifs("foo.txt.");
std::ref<std::ifstream> ifs_ref(ifs);
That works in a lot of cases where doing a regular by-ref wouldn't.
semantically, a reference is a pointer. so your code doesn't compile for the same reason this code doesn't:
main()
{
ifstream* ifs("foo.txt");
}
as others have said, you want to create an object of type ifstream. not a reference (nor a pointer) to it.
Related
In C++98, the following code does not compile because the ifstream has no copy constructor:
#include <iostream>
#include <fstream>
using namespace std;
ifstream f() {
return ifstream("main.cpp");
}
int main() {
ifstream st= f();
}
However using multiple GCC versions with C++11, this compiles without warnings. What is the reason of this?
C++11 added move constructors. The stream is now moved. The source object here is a temporary in the return expression, which can be moved to the st object in main.
In many answers and questions such as this one, it is recommended to use cin.getline from <string> and not getline(cin, variable):
#include <iostream>
#include <string>
using namespace std;
int main() {
string name;
cin.getline(name);
}
But in my case I have build issue:
g++ foo.cpp
foo.cpp: In function ‘int main()’:
foo.cpp:8:21: error: no matching function for call to
‘std::basic_istream<char>::getline(std::string&)’
8 | cin.getline(name);
| ^
From the error told by the compiler, it is evident that there is no such function overload that accepts a type reference to std::string (for cin.getline()). Rather, it accepts parameters like:
const int MAX = 100;
char input[MAX];
cin.getline(input, MAX);
// Or better
// cin.getline(input, sizeof input);
Can't compile this small code on Linux:
#include <fstream>
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(){
char fileName[512];
sprintf(fileName, "test");
ofstream iriFile(string(fileName));
iriFile<<",";
return 0;
}
I am compiling like this: g++ test.cpp and am getting this:
test.cpp:12:11: error: invalid operands of types
‘std::ofstream(std::__cxx11::string) {aka
std::basic_ofstream(std::__cxx11::basic_string)}’ and
‘const char [2]’ to binary ‘operator<<’ iriFile<<",";
What might be the reason?
Ok, the solution is to remove implicit string() creation:
string sFileName(fileName)
ofstream iriFile(sFileName);
First of all you do not need to explicitly convert const char * to std::string there is std::ifstream constructor for it:
std::ofstream iriFile(fileName);
but if you want to be extra safe and verbose use proper C++ then:
std::ofstream iriFile( static_cast<std::string>(fileName) );
not C style cast.
As you pointed out, removing the explicit string creation fixes it.
It could be worth to add that this can also be fixed for types with explicit constructors by using list initialization, like so:
ofstream iriFile(string{sFileName});
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;
I am trying to change a certain text box message. It will display my output.
This is what I have in my main()
#include "form2.h"
....
string recvMSG = "random";
182:: Form2::changeOutput(recvMSG);
...
within my form2.h I have:
#include <string.h>
#include <iostream>
#include <stdlib.h>
...
void Form2::changeOutput(string s)
{
QString s1 = i18n(s);
output_box.setText(s1);
}
But i still get:
.ui/form2.h:56: error: ‘string’ has not been declared
Thanks.
Edit:: kk so now its showing::
TCPClient.cpp:182: error: cannot call member function ‘virtual void Form2::changeOutput(std::string)’ without object
string is in the std namespace, so you either need to refer to it as std::string, or you need to make the name available in the current scope with using namespace std; or using std::string;.
Also the header is called string, not string.h, so include it this way:
#include <string>
Generally you also might want to use QT's QString instead of std::string if you are using it in connection with QT components that usually take QString parameters.
I guess you should use the header <string> and then use std::string (even better would be const std::string &)