【问题标题】:How can I display the content of a map on the console?如何在控制台上显示地图的内容?
【发布时间】:2010-11-07 00:00:18
【问题描述】:

我有一个map 声明如下:

map < string , list < string > > mapex ; list< string > li;

如何在控制台上显示上述地图中存储的项目?

【问题讨论】:

    标签: c++ dictionary stl stdmap


    【解决方案1】:

    我会尝试以下方法

    void dump_list(const std::list<string>& l) {
      for ( std::list<string>::const_iterator it = l.begin(); l != l.end(); l++ ) {
        cout << *l << endl;
      }
    }
    
    void dump_map(const std::map<string, std::list<string>>& map) {
      for ( std::map<string,std::list<string>>::const_iterator it = map.begin(); it != map.end(); it++) {
        cout << "Key: " << it->first << endl;
        cout << "Values" << endl;
        dump_list(it->second);
    }
    

    【讨论】:

    • 在第一行得到expected unqualified-id before '&lt;' tokenvoid dump_list(const std::list&lt;string&gt;&amp; l) {。我必须包括一些东西吗?
    • 在 dump_list 中应该是这样的: std::vector::const_iterator it = l.begin(); for ( it; it != l.end(); ++it ) { std::cout
    【解决方案2】:

    这取决于你想如何显示它们,但你总是可以轻松地迭代它们:

    typedef map<string, list<string>>::const_iterator MapIterator;
    for (MapIterator iter = mapex.begin(); iter != mapex.end(); iter++)
    {
        cout << "Key: " << iter->first << endl << "Values:" << endl;
        typedef list<string>::const_iterator ListIterator;
        for (ListIterator list_iter = iter->second.begin(); list_iter != iter->second.end(); list_iter++)
            cout << " " << *list_iter << endl;
    }
    

    【讨论】:

    • @triclosan:你也可以预先增加,在这种情况下没关系。还是我误会了你?
    • 使用后增量增益来创建额外的临时对象
    • @triclosan:也许,或者编译器会为您优化它。不试就说不出来。在总体方案中,我们使用标准 iostream 控制台输出,这在性能方面使额外对象迭代器对象的任何成本相形见绌。
    【解决方案3】:

    我有点跑题了……

    我猜你想转储地图内容以进行调试。我想提一下,下一个 gdb 版本(7.0 版)将有一个内置的 python 解释器,gcc libstdc++ 将使用它来提供 stl 漂亮的打印机。这是您的案例的示例

      #include <map>
      #include <map>
      #include <list>
      #include <string>
    
      using namespace std;
    
      int main()
      {
        typedef map<string, list<string> > map_type;
        map_type mymap;
    
        list<string> mylist;
        mylist.push_back("item 1");
        mylist.push_back("item 2");
        mymap["foo"] =  mylist;
        mymap["bar"] =  mylist;
    
        return 0; // stopped here
      }
    

    导致

    (gdb) print mymap
    $1 = std::map with 2 elements = {
      ["bar"] = std::list = {
        [0] = "item 1",
        [1] = "item 2"
      },
      ["foo"] = std::list = {
        [0] = "item 1",
        [1] = "item 2"
      }
    }
    

    耶!

    【讨论】:

      【解决方案4】:

      另一种形式,使用&lt;algorithm&gt;:

      void printPair(const pair<string, list<string> > &p)
      {
          cout << "Key: " << p.first << endl;
          copy(p.second.begin(), p.second.end(), ostream_iterator<string>(cout, "\n"));
      }    
      for_each(mapex.begin(), mapex.end(), printPair);
      

      测试程序:

      #include <iostream>
      #include <map>
      #include <list>
      #include <iterator>
      #include <algorithm>
      using namespace std;
      
      void printPair(const pair<string, list<string> > &p)
      {
          cout << "Key: " << p.first << endl;
          copy(p.second.begin(), p.second.end(), ostream_iterator<string>(cout, "\n"));
      }
      
      int main()
      {
          map<string, list<string> >  mapex;
      
          list<string> mylist1;
          mylist1.push_back("item 1");
          mylist1.push_back("item 2");
          mapex["foo"] =  mylist1;
          list<string> mylist2;
          mylist2.push_back("item 3");
          mylist2.push_back("item 4");
          mylist2.push_back("item 5");
          mapex["bar"] =  mylist2;
      
          for_each(mapex.begin(), mapex.end(), printPair);
      }
      

      【讨论】:

        【解决方案5】:

        更新(回到未来):使用 C++11 基于范围的 for 循环 –

        std::map<Key, Value> m { ... /* initialize it */ ... };
        
        for (const auto &p : m) {
            std::cout << "m[" << p.first << "] = " << p.second << '\n';
        }
        

        【讨论】:

          【解决方案6】:

          你可以编写一个非常通用的重载函数,这有两个好处:

          1. 它适用于任何map
          2. 它允许使用&lt;&lt;

          功能是

          template<class key_t, class value_t>
          ostream& operator<<(ostream& os, const map<key_t, value_t>& m) {
              for (typename map<key_t, value_t>::const_iterator it = m.begin();
                      it != m.end(); it++) {
                  os << "Key: " << it->first << ", Value: " << it->second;
              }
              return os;
          }
          

          cout &lt;&lt; 将适用于为 &lt;&lt; 定义为 typenames key_tvalue_t 的任何 map。在您的情况下,这不是为 value_t (= list&lt;string&gt;) 定义的,因此您还必须定义它。 本着类似的精神,您可以使用

          template<class T>
          ostream& operator<<(ostream& os, const list<T>& l) {
              for (typename list<T>::const_iterator it = l.begin(); it != l.end(); it++) {
                  os << "\"" << *it << "\", ";
              }
              return os;
          }
          

          所以,你可以:

          1. 添加这两个函数。
          2. 在需要的地方添加原型。
          3. 使用using namespace std;(或根据需要添加std::)。
          4. 使用,例如,
            cout &lt;&lt; mapex &lt;&lt; endl;
            cout &lt;&lt; li &lt;&lt; endl;

          请记住,如果刚刚定义的&lt;&lt;s 有任何其他可行的候选人(我认为没有,否则您可能不会问这个问题),它可能优先于当前的候选人。

          【讨论】:

            【解决方案7】:

            如果您可以使用C++11 功能,那么我认为The Paramagnetic Croissant's answer 中提出的range-based for loops 提供了最易读的选项。但是,如果您可以使用C++17,那么您可以将这些循环与structured bindings 结合起来以进一步提高可读性,因为您不再需要使用firstsecond 成员。对于您的特定用例,我的解决方案如下所示:

            std::map<std::string, std::list<std::string>> mapex;
            mapex["a"] = { "1", "2", "3", "4" };
            mapex["b"] = { "5", "6", "7" };
            
            for (const auto &[k, v] : mapex) {
                std::cout << "m[" << k.c_str() << "] =";
                for (const auto &s : v)
                    std::cout << " " << s.c_str();
                std::cout << std::endl;
            }
            

            输出:

            m[a] = 1 2 3 4
            m[b] = 5 6 7

            Code on Coliru

            【讨论】:

              猜你喜欢
              • 2014-01-13
              • 2016-03-18
              • 2018-11-02
              • 2022-06-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-03-23
              相关资源
              最近更新 更多