我想解析文件的内容并加载到地图中。
这是文件内容格式:
Movie-name release-year price cast ishd
"DDLG" 2010 20.00 "shahrukh and Kajal" true
"Aamir" 2008 10.00 "abc, xyz and ijkl" false
地图键将是第一个单词(电影名称)。
班级定义:
class movieInfo
{
private:
int releaseYear;
double price;
string cast;
bool isHD;
};
这是我想要实现的功能。
void fill_map_contents (map <string, movieInfo*> &mymap, ifstream& myfile)
{
string line;
string word;
while (getline(myfile, line))
{
out << "inside while loop " << line << endl;
stringstream tokenizer;
tokenizer << line;
movieInfo *temp = new movieInfo;
while (tokenizer >> word)
{
cout << " printing word :->"<< word << endl;
//temp->releaseYear = atoi(word);
//temp->price = 12.34;
//temp->cast = "sahahrukh salman";
//temp->isHD = false;
mymap[word] = temp;
}
delete temp;
}
}
我不知道,在while(tokenizer&gt;&gt; word)之后,如何填充对象变量并将其分配给地图。
任何帮助都将受到高度赞赏。
Devesh
答案 0 :(得分:2)
cout << " printing word :->"<< word << endl;
//temp->releaseYear = atoi(word);
//temp->price = 12.34;
//temp->cast = "sahahrukh salman";
//temp->isHD = false;
在上面的代码中,您试图直接访问该类的私有成员,这是不可能的。因此,更好的解决方案是您应该为每个变量包含公共getter / setter,如下所示。
public:
void setreleaseYear(int sry){releaseYear=sry;}
void setprice(double pr){price=pr;}
void setcast(string cast){string=str;}
void setisHD(bool id){isHD=id;}
现在用来代替评论代码:
//temp->releaseYear = atoi(word);
temp->setreleaseYear(atoi(word));
tokenizer >> word;
//temp->price = 12.34;
temp->setprice(atof(word));
tokenizer >> word;
//temp->cast = "sahahrukh salman";
temp->setcast(word);
tokenizer >> word;
//temp->isHD = false;
temp->setisHD(word);
不需要while循环。
答案 1 :(得分:0)
你必须简化一些事情。我建议为movieinfo
添加inserction和extract运算符,并选择new line as field separator
DDLG
2010
20.00
shahrukh and Kajal
true
Aamir
2008
10.00
abc, xyz and ijkl
false
class movieInfo
{
public:
int releaseYear;
double price;
string cast;
bool isHD;
friend std::ostream& operator << ( std::ostream& os, const movieinfo& i )
{
return os << i.releaseYear << '\n'
<< i.price << '\n'
<< i.cast << '\n'
<< std::boolalpha << i.isHD() << '\n';
}
friend std::istream& operator >> ( std::istream& is, movieinfo& i )
{
is >> i.releaseYear
>> i.price;
getline( is, i.cast );
return is >> std::boolalpha >> i.isHD;
}
};
void fill_map_contents (map <string, movieInfo> &mymap, ifstream& myfile)
{
while ( !myfile.eof )
{
string name;
myfile >> name;
movieInfo mi;
myfile >> m1;
mymap[ name ] = movieInfo;
}
}
请注意,我更改了map <string, movieInfo*>
map <string, movieInfo>
更喜欢使用移动语义。
另一个建议我将改变moveinfo:
class movieInfo
{
public:
// ctor and move, assign operator and move operator
int releaseYear() const { return mReleaseYear; };
double price() const { return mPrice; };
const string& cast() const { return mCast; };
bool isHD() const { return mIsHD; };
private:
int mReleaseYear;
double mPrice;
string mCast;
bool mIsHD;
friend std::ostream& operator << ( std::ostream& os, const movieinfo& i )
{
return os << i.releaseYear() << '\n'
<< i.price() << '\n'
<< i.cast() << '\n'
<< std::boolalpha << i.isHD() << '\n';
}
friend std::istream& operator >> ( std::istream& is, movieinfo& i )
{
is >> i.mReleaseYear
>> i.mPrice;
getline( is, i.mCast );
return is >> i.mIsHD;
}
};
答案 2 :(得分:0)
您实际上是在尝试解析CSV file,空格为分隔符,"
为引号字符。
我建议使用库,例如this one。 示例代码(摘自帮助页面):
// Note: I changed mymap to map<string, movieInfo> without a pointer - it's not
// needed
const char field_terminator = ' '; // Use a space
const char line_terminator = '\n'; // Use line break
const char enclosure_char = '"'; // Use "
csv_parser file_parser;
file_parser.set_skip_lines(1);
file_parser.init(filename);
file_parser.set_enclosed_char(enclosure_char, ENCLOSURE_OPTIONAL);
file_parser.set_field_term_char(field_terminator);
file_parser.set_line_term_char(line_terminator);
while(file_parser.has_more_rows()) {
csv_row row = file_parser.get_row();
movieInfo temp; // No need for pointers
temp->releaseYear = atoi(row[1]); // C++11: Use std::stoi()
temp->price = atof(row[2]); // C++11: Use std::stof()
temp->cast = row[3];
temp->isHD = row[4].compare("true") == 0;
mymap[row[0]] = temp;
}