在 map<string, vector<std::pair<string, string>>> c++98 中存储数据

Storing data in map<string, vector<std::pair<string, string>>> c++98

我有一个名为 Bird.lst 的文件。我正在尝试读取其内容并将数据存储在 map<string, vector<pair<string, string>>> 中。这个想法是将鸟的名字存储在 string 中,并将其属性值存储在 vector.

此外,还有一些我不需要的属性(vaccinatedbabiessale)。插入 map 时,我必须检查是否插入这些属性。

没有添加属性,但是在显示的时候,那里的map内容显示的是空格。我想摆脱 map.

中的空行

我的map内容应该如下图所示。请帮助。

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

Bird.lst

parrot.sh
vaccinated  yes
eat         yes
babies      no
fly         yes
sale        no

pigeon.sh
vaccinated  yes
eat         yes
fly         yes
babies      yes
sale        yes

duck.sh
vaccinated  yes
eat         yes
fly         no
sale        yes
babies      no

flammingo.sh
vaccinated  yes
eat         yes
fly         yes
sale        no
babies      no

eagle.sh
vaccinated  yes
eat         yes
babies      no
fly         yes

代码:

#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);
            if(value.find("vaccinated") == std::string::npos && value.find("babies") == std::string::npos && value.find("sale") == std::string::npos)
            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;
}

以上代码的输出:

duck.sh

   eat   yes
   fly   no



eagle.sh

   eat   yes

   fly   yes

flammingo.sh

   eat   yes
   fly   yes



parrot.sh

   eat   yes

   fly   yes


pigeon.sh

   eat   yes
   fly   yes

在插入 map 之前,这里的值是 vector> > 添加检查值向量字符串是否不为空。

#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);
            if(value.find("vaccinated") == std::string::npos && value.find("babies") == std::string::npos && value.find("sale") == std::string::npos)
            ss >> attribute.first >> attribute.second;
            
            if(!attribute.first.empty())  //check the attribute value is empty or not before inserting into attributes vector
            // 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;
}

当您将 value 字符串解析为 attribute_pair 时,您正在寻找要忽略的特定属性,如果找到一个,则不会解析 value ,但您仍在将 empty attribute_pair 插入 attributes 向量中。这就是输出中空行的来源。

改变这个:

// now split the value into an attribute and a flag
attribute_pair attribute;
std::istringstream ss(value);
if(value.find("vaccinated") == std::string::npos && value.find("babies") == std::string::npos && value.find("sale") == std::string::npos)
ss >> attribute.first >> attribute.second;

// save the value into the vector
attributes.push_back(attribute);

改为:

// now split the value into an attribute and a flag
attribute_pair attribute;
std::istringstream ss(value);
ss >> attribute.first >> attribute.second;
if(attribute.first != "vaccinated" && attribute.first != "babies" && attribute.first != "sale") {
    // save the value into the vector
    attributes.push_back(attribute);
}

Online Demo

也就是说,您可以考虑 using a map<string,string> instead of a vector<pair<string,string>>,除非您需要保留每只鸟属性的原始顺序(您没有保留鸟本身的顺序,因为 std::map 已排序)。