如何解析文件的内容并加载到地图中

时间:2013-10-31 11:08:22

标签: c++ map stl stringstream

我想解析文件的内容并加载到地图中。

这是文件内容格式:

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

3 个答案:

答案 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;
}