【问题标题】:To read FILE and store data in map<string, vector<string>> c++98在 map<string, vector<string>> c++98 中读取 FILE 和存储数据
【发布时间】:2021-06-18 18:10:15
【问题描述】:

我有文件bird.lst,我需要读取文件内容并将数据存储在map中,这里的想法是鸟名存储在字符串中,而那些有一些属性值需要存储在向量.请帮忙

最终 map 如下所示, 例如:

 parrot.sh   ---->  eat    yes
                    fly    yes

bird.lst 下面的文件内容

parrot.sh
eat    yes
fly    yes

pigeon.sh
eat    yes
fly    yes

duck.sh
eat   yes
fly   no

flammingo.sh
eat   yes
fly   yes

eagle.sh
eat    yes
flay   yes

【问题讨论】:

  • 你实际上并没有说你有什么样的问题让它工作,所以我已经做了一个答案 - 如果它没有真正回答你的问题,请告诉我。
  • @JerryJeremiah 这个解决方案非常适合我。谢谢

标签: c++ file dictionary vector c++98


【解决方案1】:

你需要一个嵌套循环。

  • 外面的人读鸟的名字(地图的关键)
  • 里面读取鸟的属性(向量的值)

这是我想出的:

#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <vector>


typedef std::vector<std::string> attribute_vector;
typedef std::map<std::string,attribute_vector> bird_map;

int main()
{
    std::ifstream file("bird.lst");

    bird_map birds;
    std::string key;
    while(std::getline(file,key))
    {
        attribute_vector attributes;
        std::string value;
        while(std::getline(file,value))
        {
            // in case it has windows encoding with end-of-line = \r\n
            if (!value.empty() &&
                value[value.size()-1] == '\r')
            {
                value.erase(value.size() - 1);
            }

            // if we found the empty string
            if(value.empty())
            {
                break;
            }

            // save the value into the vector
            attributes.push_back(value);
        }
        // save the bird into the map
        birds[key] = attributes;
    }

    // now print the data we collected
    for(bird_map::iterator bird = birds.begin();
        bird != birds.end();
        bird++)
    {
        std::cout << bird->first << "\n";
        for(attribute_vector::iterator attribute = bird->second.begin();
            attribute != bird->second.end();
            attribute++)
        {
            std::cout << "    " << *attribute << "\n";
        }
        std::cout << "\n";
    }

    return 0;
}

https://onlinegdb.com/1TBobUxE2 尝试它(它说C++17 作为编译器类型,但在“Extra Compiler Flags”下的配置中我传递-std=c++98

如果你想从是/否值中拆分属性,那么:

#include <fstream>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include <utility>

typedef std::pair<std::string,std::string> attribute_pair;
typedef std::vector<attribute_pair> attribute_vector;
typedef std::map<std::string,attribute_vector> bird_map;

int main()
{
    std::ifstream file("bird.lst");

    bird_map birds;
    std::string key;
    while(std::getline(file,key))
    {
        attribute_vector attributes;
        std::string value;
        while(std::getline(file,value))
        {
            // in case it has windows encoding with end-of-line = \r\n
            if (!value.empty() &&
                value[value.size()-1] == '\r')
            {
                value.erase(value.size() - 1);
            }

            // if we found the empty string
            if(value.empty())
            {
                break;
            }

            // now split the value into an attribute and a flag
            attribute_pair attribute;
            std::istringstream ss(value);
            ss >> attribute.first >> attribute.second;

            // save the value into the vector
            attributes.push_back(attribute);
        }
        // save the bird into the map
        birds[key] = attributes;
    }

    // now print the data we collected
    for(bird_map::iterator bird = birds.begin();
        bird != birds.end();
        bird++)
    {
        std::cout << bird->first << "\n";
        for(attribute_vector::iterator attribute = bird->second.begin();
            attribute != bird->second.end();
            attribute++)
        {
            std::cout << "   " << attribute->first
                      << " = " << attribute->second
                      << "\n";
        }
        std::cout << "\n";
    }

    return 0;
}

https://onlinegdb.com/Htlh4eHu9 尝试它(它说C++17 作为编译器类型,但在“Extra Compiler Flags”下的配置中我传递-std=c++98

【讨论】:

    【解决方案2】:

    (问题) 问题不是很具体。 因此,我将尝试制定一个非常通用的解决方案。 定义一个函数:

    bool is_file(string s) {
       return (s.substr((int)s.size() - 3, 3) == ".sh");
    }
    

    告诉你一个字符串是否是一个鸟文件。

    由于(Issue),我假设鸟的每个属性都具有以下形式:(attribute, yes/no),我们将转换为 (attribute, 1/0 )。

    现在,要读取文件,您有多种选择。我会说出其中两个的名字。

    1. 从控制台传递文件,即如果你的 .exe 被称为birds.exe,只需执行birds.exe

    2. 使用 freopen("bird.lst", "r", stdin);只需使用 std::cin 阅读即可。

    那么,主函数应该是这样的:

    int main () {
       freopen("bird.lst", "r", stdin); // if you didnt read from console.
       map<string, vector<pair<string, bool>>> birds;
       string current_bird;
       while (cin >> s) {
           string s;
           cin >> s;
           if (is_file(s)) {
              current_bird = s;
              continue;
           }
           bool verdict;
           cin >> verdict;
           bird[current_bird].push_back(make_pair(s, verdict));
       }
    }
    

    并打印数据:

    for (auto it = birds.begin(); it != birds.end(); it++) {
       cout << "Bird File: " << it.first << "\n";
       cout << "Attributes:\n";
       for (auto x : it.second) cout << x.first << " " << (x.second ? "YES" : "NO") << "\n";
    }
    

    【讨论】:

    • is_file 中你有一个错字,你使用n 而不是s 并且在c++98 中你不能在最后使用&gt;&gt;&gt; 嵌套模板 - 你需要中间有空格,因为当 c++98 编译器连续看到两个 &gt; 时,它是一个右移运算符。而在 c++98 中,auto 并没有达到预期的效果。
    • 我明白了。嗯,你知道该怎么做哈哈。我修正了错字并添加了打印算法。我真的想要最好的答案,所以我得到更多的好处哈哈,我是新手,我几乎没有:c
    • 对于自动问题,将其替换为 map>>::iterator :D
    • 还有一堆其他的bug,其中最严重的就是cin &gt;&gt; verdict;当文件包含yesno的字符串时转成bool变量,如果你想用,这里是一个修复了所有这些错误的版本:onlinegdb.com/Bk1mGhBNd
    猜你喜欢
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多