简体   繁体   English

打印其中带有地图的结构

[英]printing a struct with a map in it

Ok I am having trouble printing the values in my list of structs. 好的,我在打印结构列表中的值时遇到麻烦。 The normal way of printing a list (with the iterator) is not working. 打印列表(使用迭代器)的常规方法不起作用。 This is my code of me reading in a file into my list. 这是我将文件读入列表的代码。

struct Edge{
    map<char, string> edge;
    int weight= -1;

    Edge(){};
    Edge(char v, string e, int w){
      edge.insert(pair<char,string>(v,e));
      weight = w;
    }
};

int main(){
     list<Edge> edges;

        //Read in file//
string line;
char start;
vector<string> tokens;

if(!file.is_open()){
    cout<<"Could not open file\n";
}else{
    while(getline(file,line)){
        tokens.clear();
        start = line.front();
        istringstream iss(line);
        copy(istream_iterator<string>(iss), 
            istream_iterator<string>(),
            back_inserter<vector<string>>(tokens));
        for(int i = 1; i<tokens.size(); i+=2){
            //cout << "Position: " <<i << " = " << tokens.at(i) <<endl;
            //insert into edges list.
                Edge e = Edge(start, tokens.at(i), stoi(tokens.at(i+1)));
                edges.push_back(e);
        }//end for
    }//end while
}//end if-else

 return 0;
}//end main

The vector tokens is read in properly. 矢量标记已正确读取。 I checked it with the commented out cout. 我用注释掉的cout检查了它。

The file is a graph file with the first element the start vertex and the rest of the line is formatted with the end vertex of the edge and the weight of that edge. 该文件是一个图形文件,第一个元素是起始顶点,而行的其余部分则以边的结束顶点和该边的权重进行格式化。

For example: 例如:

1 2 3 4 5

Would mean edge (1,2) has a weight of 3 and edge (1,4) has a weight of 5. 表示边缘(1,2)的权重为3,边缘(1,4)的权重为5。

I don't know if I read in my list properly because I can't figure out how to print it out. 我不知道我是否能正确阅读清单,因为我不知道如何打印出来。 How would I print out my list edges ? 我将如何打印列表边缘?

Or is there a better way to set up my struct? 还是有更好的方法来设置我的结构? Perhaps another struct for the edge and then a struct with the edge and weight? 也许是边缘的另一个结构,然后是边缘和重量的结构?

Printing tried that won't work. 打印尝试不起作用。 The syntax doesn't even work. 语法甚至不起作用。 :( :(

The regular way to print a list. 打印列表的常规方法。 But doesn't like it since I have a struct list. 但是不喜欢它,因为我有一个结构体列表。

    list<Edge>::iterator it;
    for(it=edges.begin(); it!=edges.end(); it++){
    cout << *it <<endl;
}//end for

And this was what I found when I searched. 这就是我搜索时发现的。 This is what I found. 这就是我发现的。 C++ How to loop through a list of structs and access their properties This is my attempt. C ++如何遍历结构列表并访问其属性这是我的尝试。

//inside main
    list<Edge>::iterator it;
for(int i = 0; i<edges.size(); i++){
    for_each(edges.begin(), edges.end(), printEdges);
}//end for

//outside main
    void printEdges(Edge &data){
    cout << "( " << data.edge << " )"
     << ": Weight = " << data.weight <<endl;
    }//end printEdges

Thank you. 谢谢。

Update to comment: 更新评论:

friend std::ostream& operator<<(std::ostream& os, Edge const& edge)
{
    os << "Edge { weight:" << edge.weight << " {\n";
    for(edge_map::const_iterator it=edge.edge.begin(); it!=edge.edge.end(); ++it)
    {
        os << "{ '" << it->first << "', \"" << it->second << "\" } ";
    }
    return os << "\n}";
}

Should get you started. 应该让您开始。

  1. it's int main , not void main 它是int main ,不是void main
  2. it's weight = w; 它的weight = w; , not weight = w. ,而不是weight = w.
  3. You need to increment the loop variable. 您需要增加循环变量。 i+2 has no effect. i+2无效。 Did you mean i+=2 ? 您是说i+=2吗?
  4. If you did, the loop condition should be fixed to avoid out-of-bounds addressing: 如果已这样做,则应固定循环条件,以避免超出范围的寻址:

      for(size_t i = 1; i+1<tokens.size(); i+=2){ 

    note the use of size_t to avoid mixed signed / unsigned comparison 注意使用size_t以避免混合的有signed / unsigned比较

  5. the Edge constructor should initialize weight Edge构造函数应初始化weight

  6. If you need //crutch comment s, your code should be more legible :_) 如果您需要//crutch comment ,则您的代码应更易读:_)
  7. Consider using a parser to read your input. 考虑使用解析器读取您的输入。 You severely lack input validation, format flexibility and error handling. 您严重缺乏输入验证,格式灵活性和错误处理。

  8. Oh, don't use using namespace std 哦,不要using namespace std

Here's an attempt at fixing some of the issues: 这是解决某些问题的尝试:

#include <string>
#include <map>
#include <list>
#include <vector>
#include <iostream>
#include <iterator>

#include <sstream>
#include <fstream>
#include <algorithm>

struct Edge{
    typedef std::map<char, std::string> edge_map;
    edge_map edge;
    int weight;

    Edge() : edge(), weight(0) {};
    Edge(char v, std::string e, int w) : edge(), weight(w)
    {
        edge.insert(std::pair<char,std::string>(v,e));
        weight = w;
    }

    friend std::ostream& operator<<(std::ostream& os, Edge const& edge)
    {
        os << "Edge { weight:" << edge.weight << " {\n";
        for(edge_map::const_iterator it=edge.edge.begin(); it!=edge.edge.end(); ++it)
        {
            os << "{ '" << it->first << "', \"" << it->second << "\" } ";
        }
        return os << "\n}";
    }
};

int main()
{
    std::list<Edge> edges;

    std::string line;
    std::vector<std::string> tokens;

    std::ifstream file("input.txt");

    if(!file.is_open()){
        std::cout<<"Could not open file\n";
    }else{
        while(std::getline(file,line)){
            tokens.clear();
            char start = line.front();
            std::istringstream iss(line);
            std::copy(std::istream_iterator<std::string>(iss), 
                    std::istream_iterator<std::string>(),
                    std::back_inserter<std::vector<std::string>>(tokens));
            for(size_t i = 1; i+1<tokens.size(); i+=2){
                Edge e = Edge(start, tokens.at(i), stoi(tokens.at(i+1)));
                edges.push_back(e);
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM