Bar chart help, no errors, won't run

Hey guys, me again. So I have to build a program where I have 4 cities, and the user inputs the population for them. Then my output has to produce a bar chart like so:

City 1: *******
City 2: ***
City 3: ********
City 4: *****

So far my code looks like this, and I feel like I have it, my IDE doesn't show any errors but when I go to run it it tells me there's build errors. I'm not sure what I'm doing wrong.


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
29
30
 #include <iostream>
using namespace std;

int main()
{
	const int CITY_NUMBER = 4;
	int population[CITY_NUMBER];

	for (int city = 0; city < CITY_NUMBER; city++)
	{
		do
		{
			cout << "Enter the population of city " << city << ": ";
			cin >> population[CITY_NUMBER];

			if (population < 0)
			{
				cout << "Population can’t be negative. Please re-enter: ";
				cin >> population[CITY_NUMBER];
				population[CITY_NUMBER] = population[CITY_NUMBER] / 1000;
			}
		} while (population < 0);
	}
	cout << "City " << city << ": ";
	for (int city = 0; city < CITY_NUMBER; city++)
	{
		cout << "*";
	}
	return 0;
}
Hello morganniie,

Line 24 flagged as an error in my MSVS 2017. Also produced an error when I compiled it.

Where is "city" defined and it is not in line 9. That is a local variale that is destroyed at the close of the for loop.

I am thinking that "city" could be defined as a "std::string" array of names that could be used in the second for loop.

And if I read this correctly the 2nd for loop will print 4 * for each city. "CITY_NUMBER" need replaced with "population" divided by some value, Since I do not know values you are using for "population", maybe by 1000 or 10,000. Also you might want to consider making "population" a "double" instead of an "int".

Andy
Hello morganniie,

You are on the right track, but not quite there.

See how this works and compare it to what you have:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <iomanip>  // <--- Added.
#include <limits>   // <--- Added.
#include <string>   // <--- Added.

using namespace std;  // <--- Best not to use.

int main()
{
    constexpr int CITY_NUMBER{ 4 };
    constexpr int POP_Divisor{ 100'000 };
    constexpr int WIDTH{ 12 };
    const std::string PROMPT{ "Enter the population of city " };
    const std::string cities[]{ "Columbus", "Cleveland", "Dayton", "Cincinnatti" };

    int population{};
    //int populationArr[CITY_NUMBER]{};  // <--- ALWAYS initialize all your variables.
    int populationArr[CITY_NUMBER]{ 878553, 385284, 140569, 301394 }; // <--- Used for testing. Reverse comment or remove when finished.

    for (int city = 0; city < CITY_NUMBER; city++)  // <--- Comment the whole for loop for testing.
    {
        while (std::cout << PROMPT + cities[city] + ": " && !(std::cin >> population) || population < 0)
        {
            if (!std::cin)
            {
                std::cerr << "\n     Invalid Input! Must be a number.\n\n";

                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
            }
            else if (population < 0)
            {
                std::cerr << "\n     Number must a positive value!\n\n";
            }
        }

        populationArr[city] = population;
    }

    std::cout << "\n\n";

    for (int index = 0; index < CITY_NUMBER; index++)
    {
        cout << "City " << std::setw(WIDTH) << cities[index] << ": ";

        for (int idx = 0; idx < (populationArr[index] / POP_Divisor); idx++)
        {
            cout << "*";
        }

        std::cout << "\n";
    }

    std::cout << "\n\n 1 * = 100,000.\n";

    return 0;  // <--- Not required, but makes a good break point for testing.
} 

When you know that the input is working comment lines 20 - 38. Line 40 is optional.

This allows you to test lines 42 - 54 without having to enter numbers each time you test the program.

Andy
Simplified perhaps:

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
29
30
31
32
33
34
35
36
#include <iostream>
#include <iomanip>
#include <limits>
#include <string>

template<typename T = int>
auto getNum(const std::string& prm)
{
	const auto notsp {[&]() {while (std::isspace(static_cast<unsigned char>(std::cin.peek())) && std::cin.peek() != '\n') std::cin.ignore(); return std::cin.peek() != '\n'; }};
	T n {};

	while ((std::cout << prm) && (!(std::cin >> n) || notsp())) {
		std::cout << "Not a number\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}

int main()
{
	constexpr size_t CITY_NUMBER {4};
	constexpr int popDivisor {1000};

	int population[CITY_NUMBER] {};

	for (size_t city = 0; city < CITY_NUMBER; population[city++] /= popDivisor)
		do {
			population[city] = getNum("Enter the population of city " + std::to_string(city + 1) + ": ");
		} while (population[city] < 0 && (std::cout << "Population can't be negative. Please re-enter\n"));

	for (size_t city = 0; city < CITY_NUMBER; ++city)
		std::cout << "City " << city + 1 << ": " << std::setfill('*') << std::setw(population[city]) << '*' << '\n';
}

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
29
30
31
32
33
34
35
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

void getCity( string &name, int &pop )
{
   cout << "Enter city name: ";   getline( cin, name );
   string dummy;
   cout << "Enter population of " << name << ": ";   cin >> pop;   getline( cin, dummy );
   if ( pop <= 0 ) 
   {
       cout << "Population must be positive\n";
       getCity( name, pop );
   }
}

int main()
{
   const int CITY_NUMBER = 4;
   int population[CITY_NUMBER];
   string names[CITY_NUMBER];

   for ( int i = 0; i < CITY_NUMBER; i++ )
   {
      cout << "City " << i + 1 << ":\n";
      getCity( names[i], population[i] );
   }
   
   double scale = 1.0e-5;
   for ( int i = 0; i < CITY_NUMBER; i++ )
   {
      cout << setw( 20 ) << left << names[i] << " " << string( (int)( scale * population[i] + 0.5 ), '*' ) << '\n';
   }
}


City 1:
Enter city name: Manchester
Enter population of Manchester: 554000
City 2:
Enter city name: Liverpool
Enter population of Liverpool: 579000
City 3:
Enter city name: Birmingham
Enter population of Birmingham: 1154000
City 4:
Enter city name: Coventry
Enter population of Coventry: 369000
Manchester           ******
Liverpool            ******
Birmingham           ************
Coventry             ****
Last edited on
Topic archived. No new replies allowed.