我有一個地圖,其中包含字符串作爲鍵和文件名列表作爲值。 例如:Map(firstDir, list(file1,file2,file3))
地圖包含值作爲列表+如何在C++中打印
我知道,通過使用下面的代碼我可以打印值是字符串
{
cout << "Key: " << pos->first << endl;
cout << "Value:" << pos->second << endl;
}
,但如果pos->second
包含一個列表,如何顯示?
我有一個地圖,其中包含字符串作爲鍵和文件名列表作爲值。 例如:Map(firstDir, list(file1,file2,file3))
地圖包含值作爲列表+如何在C++中打印
我知道,通過使用下面的代碼我可以打印值是字符串
{
cout << "Key: " << pos->first << endl;
cout << "Value:" << pos->second << endl;
}
,但如果pos->second
包含一個列表,如何顯示?
的列表超載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;
如何使用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;
}
}
你必須決定的第一件事是怎麼做的,你要顯示的列表?也許用逗號分隔,或者換成新的一行?然後,你可以重載流輸出運算符字符串列表:
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>
向任何輸出流,它會打印出用逗號分隔的列表的值。
雖然逗號不會*分開,*他們終止每個項目:''a,b,''有兩個項目的列表 – 2010-11-02 10:27:22
使用哪個重載集裝箱流插入器庫,如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提取使用的功能或簡單地複製它elsewere(它的自包含的,但確實有其他實用程序)。
@Roger:任何計劃建議你的圖書館提升?:)我的意思是,從它的外觀來看,它至少和boost分配一樣可以提升 – 2010-11-02 11:11:57
@Armen:我不會把它稱爲一個庫(整個回購是隨機分配的);我實際上認爲Boost有一些這個,但是找不到它 – 2010-11-02 11:55:59
@Roger:我不是指回購,我的意思是更廣義的項目 – 2010-11-02 11:58:49
您希望能夠做的是創建一個模板,該模板可以輸出任何可打印的序列,即可打印項目的序列。您還希望能夠自定義如何開始,結束和分隔序列。
因此創建你自己的包裝類。現在,因爲它是你的包裝器,你可以高興地在其上運行< <而不會干擾外部命名空間。
您可以在其構造函數中使用boost :: range,或者使用模板化/結束序列或模板化集合。
另請參見您的分隔符。你可以有合理的默認值,如果你想不過,
最後,當你想打印一個,你就這樣做:
std::cout << MySequenceFormatter(seq.begin(), seq.end(), delim, startofSeq, endOfSeq) << std::endl;
當輸出地圖,你可以在之間使用一個boost :: transform_iterator在遍歷序列時轉換每個std :: pair。那麼你也可以擁有自己的格式化工具。 事實上,您可以對任何您希望使用自定義方法自行打印項目的序列執行此操作。
海峽前進版本( - :
#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
由於您使用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;
}
}
更優雅的方法是使用'std :: copy'和'std :: ostream_iterator'。你也可以指定一個自定義分隔符。 – 2010-11-02 09:56:41
@ Space_C0wb0y:你的方式更加stl風格,但我不會說它是優雅的,因爲我不相信它是非常可讀的。 – 2010-11-02 09:58:44
@ Space_C0wb0y:事情是,複製和ostream迭代器的分隔符將應用在每個元素之後,而不是在它們之間。因此,我的選擇 – 2010-11-02 10:40:16