如何在控制台上显示地图内容?

发布于 2024-07-25 15:19:24 字数 168 浏览 6 评论 0原文

我有一个 map 声明如下:

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

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

I have a map declared as follows:

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

How can I display the items stored in the above map on the console?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浅唱々樱花落 2024-08-01 15:19:24

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

std::map<Key, Value> m { ... /* initialize it */ ... };

for (const auto &p : m) {
    std::cout << "m[" << p.first << "] = " << p.second << '\n';
}

Update (Back to the future): with C++11 range-based for loops –

std::map<Key, Value> m { ... /* initialize it */ ... };

for (const auto &p : m) {
    std::cout << "m[" << p.first << "] = " << p.second << '\n';
}
行雁书 2024-08-01 15:19:24

这取决于您想要如何显示它们,但您始终可以轻松地迭代它们:

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;
}

Well it depends on how you want to display them, but you can always iterate them easily:

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;
}
太阳哥哥 2024-08-01 15:19:24

我会尝试以下

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);
}

I'd try the following

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);
}
总以为 2024-08-01 15:19:24

我在这里有点偏离主题...

我猜你想转储地图内容以进行调试。 我想提一下,下一个 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"
  }
}

Yay!

I'm a little off topic here...

I guess you want to dump the map content for debugging. I like to mention that the next gdb release (version 7.0) will have a built in python interpreter which will be used by the gcc libstdc++ to provide stl pretty printers. Here is an example for your case

  #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
  }

which results in

(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"
  }
}

Yay!

羞稚 2024-08-01 15:19:24

另一种形式,使用

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);
}

Another form, using <algorithm>:

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);

Test program:

#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);
}
木格 2024-08-01 15:19:24

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

  1. 它适用于任何map
  2. 它允许使用 <<

该函数

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 << 将适用于为 typename<< 的任何 map >s key_tvalue_t。 在您的情况下,没有为 value_t (= list) 定义它,因此您还必须定义它。
本着类似的精神,您可以使用

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<< 地图派克斯<< 结束;

    <代码>cout<< 李<< endl;

请记住,如果刚刚定义的 << 有任何其他可行的候选者(我认为没有,否则你可能不会问这个问题),它可能会优先于现在的。

You can write a quite generic overloaded function, which is good for two purposes:

  1. It works with any map.
  2. It allows for using <<.

The function is

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 << will work with any map for which << is defined for typenames key_t and value_t. In your case, this is not defined for value_t (= list<string>), so you also have to define it.
In a similar spirit, you can use

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;
}

So, you may:

  1. Add these two functions.
  2. Add the prototypes where needed.
  3. Use using namespace std; (or add std:: as needed).
  4. Use, e.g.,

    cout << mapex << endl;

    cout << li << endl;

Remember that if there is any other viable candidate for the <<s just defined (which I take there is not, otherwise you would likely not ask this question), it may take precedence over the present ones.

戈亓 2024-08-01 15:19:24

如果您可以使用 C++11 功能,那么我认为 基于范围的 for 循环,如 顺磁羊角面包的答案提供了最具可读性的选项。 但是,如果您可以使用 C++17,那么您可以结合使用那些带有 结构化绑定 的循环可进一步提高可读性,因为您不再需要使用 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

Coliru 上的代码

If you can use C++11 features, then I think range-based for loops as proposed in The Paramagnetic Croissant's answer provide the most readable option. However, if C++17 is available to you, then you can combine those loops with structured bindings to further increase readability, because you no longer need to use the first and second members. For your specific use case, my solution would look as follows:

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;
}

Output:

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

Code on Coliru

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文