【问题标题】:Reading from file separated with semicolons and storing into array从用分号分隔的文件中读取并存储到数组中
【发布时间】:2015-02-20 01:57:45
【问题描述】:

我完全迷失了,并且已经尝试了几个小时从名为“movies.txt”的文件中读取并将其中的信息存储到数组中,因为它有分号。有什么帮助吗?谢谢。

movies.txt:

The Avengers     ; 2012     ;  89    ;   623357910.79
Guardians of the Galaxy    ;   2014    ;  96    ; 333130696.46

代码:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

struct Movie {
    std::string name;
    int year;
    int rating;
    double earnings;
};

int main()
{
    const int MAX_SIZE = 100;
    Movie movieList[MAX_SIZE];
    std::string line;
    int i = 0;

    std::ifstream movieFile;
    movieFile.open("movies.txt");

    while (getline(movieFile, line, ';'))
    {
        movieFile >> movieList[i].name >> movieList[i].year >> movieList[i].rating >> movieList[i].earnings;
        i++;
    }

    movieFile.close();

    std::cout << movieList[0].name << " " << movieList[0].year << " " << movieList[0].rating << " " << movieList[0].earnings << std::endl;
    std::cout << movieList[1].name << " " << movieList[1].year << " " << movieList[1].rating << " " << movieList[1].earnings << std::endl;

    return 0;
}

我想要的是拥有:

movieList[0].name = "The Avengers";
movieList[0].year = 2012;
movieList[0].rating = 89;
movieList[0].earnings = 623357910.79;

movieList[1].name = "Guardians of the Galaxy";
movieList[1].year = 2014;
movieList[1].rating = 96;
movieList[1].earnings = 333130696.46;

【问题讨论】:

    标签: c++ arrays file structure


    【解决方案1】:

    我修改了你的代码。

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <vector>
    
    struct Movie {
        std::string name;
        int year;
        int rating;
        double earnings;
    };
    
    
    std::vector<std::string>
    split(const std::string &s, char delim = ',')
    {
    
        std::vector<std::string> elems;
    
        std::stringstream ss(s);
        std::string item;
        while (std::getline(ss, item, delim))
        {
                elems.push_back(item);
        }
        return elems;
    }
    
    
    int main()
    {
    
        std::vector<Movie> movieList;
        std::string line;
    
    
        std::ifstream movieFile;
        movieFile.open("movies.txt");
    
        while (getline(movieFile, line))
        {
            std::vector<std::string> columns = split(line,';');
            Movie movie;
    
            movie.name     = columns[0];
            movie.year     = std::stoi(columns[1]);
            movie.rating   = std::stoi(columns[2]);
            movie.earnings = std::stof(columns[3]);
    
            movieList.push_back(movie);
        }
    
        movieFile.close();
    
        for (const Movie & m: movieList) 
        {
            std::cout << m.name << " " << m.year << " " << m.rating << " " << m.earnings << std::endl;
        }
    
    
        return 0;
    }
    

    基本上,我添加了一个拆分函数,它使用“;”拆分行。我也使用向量来存储电影而不是硬编码的电影数组。这种方式好多了。

    附:没有向量的第二个版本

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <vector>
    
    struct Movie {
        std::string name;
        int year;
        int rating;
        double earnings;
    };
    
    
    
    void split(const std::string &s, char delim, std::string elems[])
    {
        std::stringstream ss(s);
        std::string item;
    
        int i = 0;
    
        while (std::getline(ss, item, delim))
        {
                elems[i++] = item;
        }
    }
    
    
    int main()
    {
    
        //std::vector<Movie> movieList;
    
        const int MAX_SIZE = 100;
        Movie movieList[MAX_SIZE];
        int movieNo = 0;
    
        std::string line;
    
    
        std::ifstream movieFile;
        movieFile.open("/home/marcin/testing/movies.txt");
    
        std::string columns[4];
    
        while (getline(movieFile, line))
        {
            split(line,';', columns);
    
            movieList[movieNo].name     = columns[0];
            movieList[movieNo].year     = std::stoi(columns[1]);
            movieList[movieNo].rating   = std::stoi(columns[2]);
            movieList[movieNo].earnings = std::stof(columns[3]);
    
            ++movieNo;
    
        }
    
        movieFile.close();
    
        for (int i =0; i < movieNo; ++i) {
            std::cout << movieList[i].name
                      << " "
                      << movieList[i].year
                      << " "
                      << movieList[i].rating
                      << " "
                      << movieList[i].earnings
                      << std::endl;
        }
    
    
        return 0;
    }
    

    【讨论】:

    • 如果我不能使用vectors atm怎么办? (这是一个班级,我的老师希望我使用数组代替这个作业)。例如,如果我必须更改“std::vector<:string> columns = split(line,';');”由于数组,我该怎么做呢?
    • @bobtran12 我在不使用向量的情况下添加了第二个版本。希望对您有所帮助。
    • 谢谢!但是,事实证明我不能使用 stoi 和 stof 任何一个大声笑(每个教练)。有什么解决方法吗?
    • 您可以使用 stringstream 对象将字符串转换为 int 和 double 等数字类型。你必须自己谷歌它。我现在没有时间,制作另一个版本。对不起。
    【解决方案2】:

    使用getline(my_movieFile, movie_name, ';') 将电影名称添加到 ;.

    如有必要,您需要弄清楚如何从名称中删除尾随空格。您可以搜索示例。

    使用getline(movieFile, line)阅读该行的其余部分

    使用std::replace 将所有; 替换为line 中的空格

    line 放入std::stringstream

    然后使用&gt;&gt; 运算符从字符串流中提取剩余字段。

    把这个循环do { ... } while (movieFile);

    另外,请勿对任意数量的电影进行硬编码。使用 std::vector&lt;Movie&gt;push_back 添加新的。

    【讨论】:

      【解决方案3】:

      我认为您想使用 std::strtok 之类的东西将您的线路分解为标记。查看参考here。该页面上给出的示例使用空格作为分隔符,您可以使用分号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-04
        相关资源
        最近更新 更多