我正在尝试实现一个从文本文件中读取数据列并将其存储在矢量中的函数,该函数可以正常工作。但是,当我尝试在一个类中实现它时,我显然错过了一些步骤。这会导致终端输出以下消息:
的外出
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;
在我的课程中,我尝试实现以下函数与其数据成员一起使用:
#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;
};
};
关于为什么这在函数内部不起作用,但是在main函数内部的任何提示?
答案 0 :(得分:6)
using namespace std;
...
vector<double> readVector(string){
// ~~~~~~^
// missing parameter name
ifstream file(string);
// ~~~~~^
// whoops, type name aka std::string instead of parameter name
您的ifstream file(string);
当前所执行的操作,它声明了一个函数file
,它按值std::string
类型的参数获取并返回std::ifstream
实例。因此你得到的错误。您可能要做的是为file
的构造函数提供路径参数:
vector<double> readVector(const string& path){
// ~~~~~~~~~~~~~~~~~^
// parameter name
ifstream file(path.c_str());
// ~~~^ ~~~~~~^
//
答案 1 :(得分:5)
此代码中的问题很多,包括:
<string>
。不要依赖另一个标题为你做这件事。Type name
)。ifstream file(string);
因此声明一个名为file
的函数,它接受string
参数并返回ifstream
(这是不可能的,因为该类不支持复制构造,但支持移动构造,而不是在这里重要。).eof()
作为循环条件,几乎总是错误(这也不例外)。 Read this for why. std::istream_iterator
为您提供此功能,应该被利用。using namespace std;
例如:
#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;
}
};
说实话,如果错误报告由调用者处理(例如空文件,向量等),你可以放弃大部分内容,此时整个成员可以简化为:
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>() };
}
这有点让人怀疑这个功能是否真正需要。呼叫者可以很容易地完全做到这一点。
答案 2 :(得分:2)
string
是您通过using namespace std
无意中提取的类型名称。因此,file
不是您的意图 - 它是一个功能std::string
并返回std::ifstream
。避免using namespace std
除非在非常受控制的范围内 - 绝对不在头文件中。
答案 3 :(得分:1)
#include <vector>
确实包括std::string
。 using namespace std;
std::string
变为类型string
后,您无法使用string
作为变量名称,因为它是一种类型。
您应该写using std::vector;
而不是using namespace std;