map包含值作为列表+如何在C ++中打印

时间:2010-11-02 09:45:19

标签: c++

我有一个地图,其中字符串作为键,文件名列表作为值。 例如:Map(firstDir, list(file1,file2,file3))

我知道通过使用以下代码我可以打印String

的值
{
    cout << "Key: " << pos->first << endl;
    cout << "Value:" << pos->second << endl;
}

但如果pos->second包含列表,如何显示?

7 个答案:

答案 0 :(得分:7)

列表

的重载operator <<
std::ostream& operator << (std::ostream& out, std::list<ListElemType> const& lst)
{
   for(std::list<ListElemType>::iterator it = lst.begin(); it != lst.end(); ++it)
   {
       if(it != lst.begin())
          out << /*your delimiter*/;  
       out << *it;
   }
   return out;
}

现在你可以做你想做的事了

cout << "Key: " << pos->first << endl << "Value:" << pos->second << endl; 

答案 1 :(得分:2)

如何使用Boost.Foreach?

#include <boost/foreach.hpp>

{
    cout << "Key: " << pos->first << endl;
    cout << "Values:" << endl;
    BOOST_FOREACH(std::string const& file, pos->second)
    {
      cout << "\t" << file << endl;
    } 
}

答案 2 :(得分:2)

您要决定的第一件事是您希望如何显示列表?也许用逗号或新行中的每个条目分隔?然后,您可以为字符串列表重载流输出运算符:

std::ostream & operator<<(std::ostream & stream, const std::list<std::string> & object) {
    std::copy(object.begin(), object.end(), std::ostream_iterator<std::string>(std::cout, ", ")
}

每次将std::list<std::string>写入任何输出流时,都会调用此运算符,它将打印以逗号分隔的列表值。

答案 3 :(得分:2)

使用一个库来重载容器的流插入器,例如my example

void example(MapType const &m) {
  using namespace kniht::container_inserters;  // must be enabled in this scope
  MapType::const_iterator x = m.begin();

  cout << *x << '\n';  // can print the pair directly

  cout << "Key: " << x->first << '\n';  // or format it yourself
  cout << "Value: " << x->second << '\n';
  // output for a list: [a, b, c]
}

您可以从我的header中提取已使用的函数,或者只是复制它(它是自包含的,但确实有其他实用程序)。

答案 4 :(得分:1)

由于您使用的是STL,因此下一个打印此类结构的最简单方法是:

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

using namespace std;

int main()
{
    map<string, list<string>> sample;

   ... //fill the map

    for (auto itr : sample){
        cout << itr.first << ":\t" << endl;
        for (auto innerItr : sample.second)
            cout << innerItr << " ";
        cout << endl;
    }
}

答案 5 :(得分:0)

您希望能够做的是创建一个可以输出任何可打印序列的模板,即一系列可打印项目。您还希望能够自定义开始,结束和分隔序列的方式。

所以创建自己的包装类。现在因为它是你的包装器,你可以重载operator&lt;&lt;很高兴它不会干扰外部命名空间。

您可以在其构造函数中使用boost :: range,或者使用模板化的/ end序列或模板化集合。

还可以将分隔符作为参数。如果你愿意,你可以有合理的默认值,

最后,当你想打印一个时,你只需要做一些事情:

std::cout << MySequenceFormatter( seq.begin(), seq.end(), delim, startofSeq, endOfSeq ) << std::endl;

输出贴图时,可以在中间使用boost :: transform_iterator转换每个std :: pair,同时遍历序列。然后你也可以拥有自己的对格式化程序。 实际上,对于您希望使用自定义方法打印项目的任何序列,您都可以执行此操作。

答案 6 :(得分:0)

海峡前进版( - :

#include <map>
#include <list>
#include <string>
#include <iostream>
#include <sstream> // only for generating testdata

typedef std::list<std::string> TStringList;
typedef std::map<std::string, TStringList> TStringListMap;

TStringListMap myMap;

int main()
{
  // Generating testdata
  for (int i=0;i<10;i++)
  {
    std::stringstream kstr;
    kstr << i;
    std::string key = kstr.str();        
    for (int ii=0;ii<=i;ii++)
    {
      std::stringstream vstr;
      vstr << ii;
      myMap[key].push_back( vstr.str() );
    }  
  }

  //Print map
  for ( TStringListMap::const_iterator it = myMap.begin(), end = myMap.end(); it != end; ++it )
  {
    std::cout << it->first<< ": ";
    for( TStringList::const_iterator lit = it->second.begin(), lend = it->second.end(); lit != lend; ++lit )
    {
      std::cout << *lit << " ";
    }
    std::cout << std::endl;
  }
  return 0;
}

输出:

0: 0
1: 0 1
2: 0 1 2
3: 0 1 2 3
4: 0 1 2 3 4
5: 0 1 2 3 4 5
6: 0 1 2 3 4 5 6
7: 0 1 2 3 4 5 6 7
8: 0 1 2 3 4 5 6 7 8
9: 0 1 2 3 4 5 6 7 8 9