J'ai un map
déclaré comme suit:
map < string , list < string > > mapex ; list< string > li;
Comment puis-je afficher les éléments stockés dans la carte ci-dessus sur la console?
Cela dépend de la façon dont vous souhaitez les afficher, mais vous pouvez toujours les répéter facilement:
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;
}
Mise à jour (Retour vers le futur): avec la gamme C++ 11 basée sur les boucles -
std::map<Key, Value> m { ... /* initialize it */ ... };
for (const auto &p : m) {
std::cout << "m[" << p.first << "] = " << p.second << '\n';
}
J'essaierais ce qui suit
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);
}
Je suis un peu hors sujet ici ...
Je suppose que vous voulez vider le contenu de la carte pour le débogage. J'aime mentionner que la prochaine version de gdb (version 7.0) aura un interpréteur python intégré qui sera utilisé par gcc libstdc ++ pour fournir de jolies imprimantes stl. Voici un exemple pour votre cas
#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
}
ce qui se traduit par
(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!
Un autre formulaire, utilisant <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);
Programme de test:
#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);
}
Vous pouvez écrire une fonction surchargée assez générique, ce qui est bon à deux fins:
map
.<<
.La fonction est
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 <<
fonctionnera avec tout map
pour lequel <<
est défini pour typename
s key_t
et value_t
. Dans votre cas, cela n'est pas défini pour value_t
(= list<string>
), vous devez donc également le définir. Dans un esprit similaire, vous pouvez utiliser
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;
}
Vous pouvez donc:
using namespace std;
(ou ajoutez std::
comme requis).cout << mapex << endl;
cout << li << endl;
N'oubliez pas que s'il existe un autre candidat viable pour le <<
s juste défini (ce que je prends pas, sinon vous ne poseriez probablement pas cette question), il peut avoir la priorité sur les présentes.
Si vous pouvez utiliser C++ 11 les fonctionnalités, alors je pense que basé sur la plage pour les boucles comme proposé dans La réponse du croissant paramagnétique fournit le plus lisible option. Cependant, si C++ 17 est à votre disposition, vous pouvez combiner ces boucles avec liaisons structurées pour augmenter encore la lisibilité, car vous n'avez plus besoin d'utiliser le first
et second
. Pour votre cas d'utilisation spécifique, ma solution se présenterait comme suit:
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;
}
Production:
m [a] = 1 2 3 4
m [b] = 5 6 7