Regarding Histogram - confused

I need help with my code, what i'm trying to accomplish is when the user using my program marks a student and gives them "X" amount of marks it'll print a star on the histogram e.g. 0-29 *

My program codes for starters



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <iomanip>
#include <map>
#include <string>
using namespace std;

int main()
{
	std::map<char, int> hist_base;
	    char ch;

	    	    while (std::cin.get(ch))
	        ++hist_base[ch];

	    std::map<char, int>::const_iterator it = hist_base.begin();
	   std::map<char, int>::const_iterator end = hist_base.end();

	    
	   for (; it != end; ++it) {
	        if (std::isprint(it->first))
	            std::cout<< std::setw(2) <<'\''<< it->first <<'\'';
	        else
	            std::cout<< std::setw(4) << static_cast<int>(it->first);

	        std::cout<<": "<< std::string(it->second, '*') <<'\n';
	   }
	   return 0;
}


Anyway i can improve, any help would be apprieciated thanks.
Last edited on
Would you mind editing your post and putting the source inside code tags? It will make it a lot more legible and folks here will be more likely to look at it.
Thanks for that, i didn't know there was a option to do it.
One thing that I find makes code like this more legible is liberal use of typedefs.

1
2
3
4
5
6
7
typedef std::map<char, int> histogram_type;
typedef histogram_type::const_iterator const_iterator;

histogram_type hist_base;
...
const_iterator it = hist_base.begin();
...


Another is to put the body of the for loop into a function and use std::for_each.

1
2
3
4
5
6
7
8
9
10
11
12
13
void write_hist(const histogram_type::value_type& value)
{
    if (std::isprint(value.first))
        std::cout<< std::setw(2) <<'\''<< value.first <<'\'';
    else
        std::cout<< std::setw(4) << static_cast<int>(value.first);

    std::cout<<": "<< std::string(value.second, '*') <<'\n';
}

...

std::for_each(hist_base.begin(), hist_base.end(), write_hist);


This eliminates the need for the const_iterator typedef mentioned above and the iterator variables themselves because the code is simplified to the point of not needing them.

I also recommend putting the code that reads the histogram data from std::cin into its own function.

1
2
3
4
5
6
7
8
9
10
histogram_type read_hist(std::istream& input)
{
    histogram_type hist_base;
    char ch;

    while (input.get(ch))
        ++hist_base[ch];

    return hist_base;
}


main() then looks like this:

1
2
3
4
5
6
int main()
{
    histogram_type hist_base = read_hist(std::cin);
    std::for_each(hist_base.begin(), hist_base.end(), write_hist);
    return 0;
}


And lastly, don't mix spaces and tabs for indentation. I recommend sticking with spaces for indentation. It looks the same for everyone.
Thanks mate.
Topic archived. No new replies allowed.