std::cout for map<string, int> - c++

I have a map declared as follows
map<string, int> symbolTable;
if(tempLine.substr(0,1) == "("){
symbolTable.insert(pair<string, int>(tempLine, lineCount));
}
How do I std::cout all of the things in my symbol table?

In modern C++:
for (auto&& item : symbolTable)
cout << item.first << ": " << item.second << '\n';
If you only have access to a pre-C++11 compiler the code would be:
for ( map<string, int>::const_iterator it = symbolTable.begin(); it != symbolTable.end(); ++it)
cout << it->first << ": " << it->second << '\n';

Here's an alternative if your compiler isn't C++11 compliant:
for (map<string, int>::iterator it = symbolTable.begin();
it != symbolTable.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
And for completeness, if it is:
for (auto& s : symbolTable)
{
cout << s.first << " " << s.second << endl;
}

You can use a loop to print all the key/value pairs. The code following is an example in C++11
for (const auto& kv : symbolTable) {
std::cout << kv.first << " " << kv.second << '\n';
}
ps: Both of other two answers pay little attention to const, which is quite sad...

Related

Set iterator got invalidated?

there is something I don't really understand. Why in the following code I have different value of *it? Before loop it is 1, and after loop it is 5
set <int> my_set{3,1,4,2,5};
set<int>::iterator it = my_set.begin();
cout << "beginning of set " << *it << endl;
for(; it != my_set.end(); ++it)
cout << *it << endl;
cout << "Beginning of set " << *it << endl;

Common print function for all variants of maps C++ STL

I am brushing up some skills on C++ STL and I wrote a basic insertion/deletion code for maps.
Below is the code.
It is taking some inputs from user and inserting/deleting accordingly.
Very simple code.
But the issue is I have to write separate print functions for every map variant.
Is there anything I can do to make it common as we do in templates?
Any help would be highly appreciated.
#include <iostream>
#include <map>
#include <unordered_map>
using namespace std;
void print(const map<int, string>& mp)
{
cout << "Contents of map: { ";
for(auto& it: mp)
{
cout << it.first << " -> " << it.second << " ";
}
cout << "}" << endl;
}
void print(const multimap<int, string>& mp)
{
cout << "Contents of multi map: { ";
for(auto& it: mp)
{
cout << it.first << " -> " << it.second << " ";
}
cout << "}" << endl;
}
void print(const unordered_map<int, string>& mp)
{
cout << "Contents of unordered map: { ";
for(auto& it: mp)
{
cout << it.first << " -> " << it.second << " ";
}
cout << "}" << endl;
}
void print(const unordered_multimap<int, string>& mp)
{
cout << "Contents of unordered multi map: { ";
for(auto& it: mp)
{
cout << it.first << " -> " << it.second << " ";
}
cout << "}" << endl;
}
int main()
{
map<int, string> mp1;
multimap<int, string> mp2;
unordered_map<int, string> mp3;
unordered_multimap<int, string> mp4;
int value = 0;
string str;
cout << "Inserting..." << endl;
while(value >= 0)
{
cout << "Enter number: ";
cin >> value;
if(value >= 0)
{
cout << "Enter string: ";
cin >> str;
mp1.insert(pair<int, string>(value, str));
mp2.insert(pair<int, string>(value, str));
mp3.insert(pair<int, string>(value, str));
mp4.insert(pair<int, string>(value, str));
}
}
print(mp1);
print(mp2);
print(mp3);
print(mp4);
value = 0;
cout << "Removing..." << endl;
while(value >= 0)
{
cout << "Enter number: ";
cin >> value;
if(value >= 0)
{
// removing by value
mp1.erase(value);
mp2.erase(value);
mp3.erase(value);
mp4.erase(value);
}
}
print(mp1);
print(mp2);
print(mp3);
print(mp4);
return 0;
}
Well, yes, that is, indeed, what templates are used for, right?
template<typename T>
void print(const T& mp)
{
cout << "Contents of map: { ";
for(auto& it: mp)
{
cout << it.first << " -> " << it.second << " ";
}
cout << "}" << endl;
}
This'll work as long as only maps, or reasonable facsimiles thereof, are passed to print() (and both keys and values in the maps have a working << overload). Otherwise, it might become necessary to use SFINAE or C++20 concepts to constrain overload resolution.

auto, error: map iterator has no member named ‘first`

map<string, int> M;
for (auto E: M)
{
cout << E.first << ": " << E.second << endl;
F << E.first << ": " << E.second << endl;
};
I am learning c++ and I am confused with auto. I am trying to convert the above code into the following code( the above code with auto works correctly)
map<string, int> M;
for (map<string, int> :: iterator p = begin(M); p != end(M); p ++ )
{
cout << p.first << ": " << p.second << endl;
F << p.first << ": " << p.second << endl;
}
I got the following error:
error: ‘std::map<std::basic_string<char>, int>::iterator’ has no member named ‘first’
cout << p.first << ": " << p.second << endl;
error: ‘std::map<std::basic_string<char>, int>::iterator’ has no member named ‘second’
cout << p.first << ": " << p.second << endl;
error: ‘std::map<std::basic_string<char>, int>::iterator’ has no member named ‘first’
F << p.first << ": " << p.second << endl;
error: ‘std::map<std::basic_string<char>, int>::iterator’ has no member named ‘second’
F << p.first << ": " << p.second << endl;
Why it does not work?
Iterators are like pointers and must be dereferenced for use:
cout << p->first << ": " << p->second << endl;
The ranged-for loop (the example with auto) did this for you.

c++ How to use a ctor from another ctor? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling another constructor when constructing an object with const members
I want the latter to use the former. How can i do that in c++?. If it's not possible why can't i make the *this = regMatrix assignment?
RegMatrix::RegMatrix(int numRow,int numCol)
{
int i;
for(i=0;i<numRow;i++)
{
_matrix.push_back(vector<double>(numCol,0));
}
}
RegMatrix::RegMatrix(const SparseMatrix &sparseMatrix)
{
RegMatrix regMatrix(sparseMatrix.getNumRow(),sparseMatrix.getNumCol());
vector<Node> matrix = sparseMatrix.getMatrix();
cout << "size: " << matrix.size() << endl;
for(std::vector<Node>::const_iterator it = matrix.begin(); it != matrix.end(); ++it )
{
cout << "Position: [" << (*it).i << ", " << (*it).j << "] Value:" << (*it).value << endl;
regMatrix._matrix[(*it).i][(*it).j] = (*it).value;
}
*this = regMatrix;
}
You can do this in the new C++0x using "Delegated Constructors".
`
RegMatrix(const SparseMatrix &sparseMatrix) : RegMatrix(sparseMatrix.getNumRow(),sparseMatrix.getNumCol())
{
vector<Node> matrix = sparseMatrix.getMatrix();
cout << "size: " << matrix.size() << endl;
for(std::vector<Node>::const_iterator it = matrix.begin(); it != matrix.end(); ++it )
{
cout << "Position: [" << (*it).i << ", " << (*it).j << "] Value:" << (*it).value << endl;
this->_matrix[(*it).i][(*it).j] = (*it).value;
}
}
`

How can I print out C++ map values?

I have a map like this:
map<string, pair<string, string>> myMap;
And I've inserted some data into my map using:
myMap.insert(make_pair(first_name, make_pair(middle_name, last_name)));
How can I now print out all the data in my map?
for(map<string, pair<string,string> >::const_iterator it = myMap.begin();
it != myMap.end(); ++it)
{
std::cout << it->first << " " << it->second.first << " " << it->second.second << "\n";
}
In C++11, you don't need to spell out map<string, pair<string,string> >::const_iterator. You can use auto
for(auto it = myMap.cbegin(); it != myMap.cend(); ++it)
{
std::cout << it->first << " " << it->second.first << " " << it->second.second << "\n";
}
Note the use of cbegin() and cend() functions.
Easier still, you can use the range-based for loop:
for(const auto& elem : myMap)
{
std::cout << elem.first << " " << elem.second.first << " " << elem.second.second << "\n";
}
If your compiler supports (at least part of) C++11 you could do something like:
for (auto& t : myMap)
std::cout << t.first << " "
<< t.second.first << " "
<< t.second.second << "\n";
For C++03 I'd use std::copy with an insertion operator instead:
typedef std::pair<string, std::pair<string, string> > T;
std::ostream &operator<<(std::ostream &os, T const &t) {
return os << t.first << " " << t.second.first << " " << t.second.second;
}
// ...
std:copy(myMap.begin(), myMap.end(), std::ostream_iterator<T>(std::cout, "\n"));
Since C++17 you can use range-based for loops together with structured bindings for iterating over your map. This improves readability, as you reduce the amount of needed first and second members in your code:
std::map<std::string, std::pair<std::string, std::string>> myMap;
myMap["x"] = { "a", "b" };
myMap["y"] = { "c", "d" };
for (const auto &[k, v] : myMap)
std::cout << "m[" << k << "] = (" << v.first << ", " << v.second << ") " << std::endl;
Output:
m[x] = (a, b)
m[y] = (c, d)
Code on Coliru
You can try range based loop like this:
for(auto& x:myMap){
cout<<x.first<<" "<<x.second.first<<" "<<x.second.second<<endl;
}
The easiest way is to declare an iterator first as
map<string ,string> :: iterator it;
and after that print it out by looping over the map using iterator from myMap.begin() to myMap.end() and print out key and value pairs in the map with it->first for key and it->second for value.
map<string ,string> :: iterator it;
for(it=myMap.begin();it !=myMap.end();++it)
{
std::cout << it->first << ' ' <<it->second;
}