Simple Programming Problem

Hi there, I have completed the program but I am having trouble with my output. It seems my "star" is outputting more more than 1 star than usual.

Question: Write a program that produces a bar chart showing the population growth of
Prairieville, a small town in the Midwest, at 20-year intervals during the past 100 years.
The program should read in the population figures (rounded to the nearest 1,000 people)
for 1900, 1920, 1940, 1960, 1980, and 2000 from a file. For each year it should display the date and a bar consisting of one asterisk for each 1,000 people. The data
can be found in the People.txt file.
Here is an example of how the chart might begin:
PRAIRIEVILLE POPULATION GROWTH
(each * represents 1,000 people)
1900 **
1920 ****
1940 *****

My Data Files which is named "Mitra.txt" contains the information:

1900 2230
1920 4899
1940 5783
1960 6466
1980 8222
2000 15248

Here is my code that is producing the problem. Thanks! Also sorry about the additional comments, I add that for my own sake to remember some stuff.

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
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

int main()
{
	ifstream inputFile; // File stream object
	inputFile.open("Mitra.txt");

	int number;
	int artesik;
	int real;

	for (int year = 1900; year <= 2000; year += 20)
	{
		cout << "For year: " << year << " ";
		inputFile >> number >> real; // Because the file reads "1900 2565" this just reads the second number.
		
		for (int i = 0; i <= real; i+=1000)
		{
			cout << "*";
		}
		cout << endl;
	}

	
	return 0;
}
Last edited on
If the years in the input file change, your program will print the wrong values. Why not print the years from the file?

Off-by-one errors are common in programming. In this case, you need to look closely at what happens near the boarders. How many stars should print if the population is 100? 1499?, 1500?, 1999? In other words, should you round off the population to the nearest thousand? Round up? Round down? Looking at the example, it appears that you should round DOWN to the nearest thousand. So populations 0-999 print zero stars, 1000-1999 prints 1, etc.

Knowing that, the answer is to change your for loop to for (int i = 1000; i <= real; i+=1000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

int
main()
{
    ifstream inputFile;		// File stream object
    inputFile.open("Mitra.txt");

    int year, population;

    while (inputFile >> year >> population) {
	cout << "For year: " << year << " ";
	for (int i = 1000; i <= population; i += 1000) {
	    cout << "*";
	}
	cout << endl;
    }

    return 0;
}

closed account (48T7M4Gy)
Or,
1
2
3
4
for (int i = 0; i < population / 1000; i++)
        {
            cout << "*";
        }
there is integer division going on in your code and you're not rounding to the nearest '000:
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
# include <iostream>
# include <fstream>
# include <iomanip>
# include <cmath>
//using namespace std; https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice

double divisor = 1000;

int main()
{
	std::ifstream inputFile{"F:\\test.txt"}; // can initialize ifstream object directly
	//inputFile.open("Mitra.txt");

	double number{}; //initialize variables upon declaration
	//int artesik; unused variable
	double real{};

	for (double year = 1900; year <= 2000; year += 20)
	{
		std::cout << "For year: " << year << " ";
		inputFile >> number >> real; // Because the file reads "1900 2565" this just reads the second number.

		for (double i = 0; i <= (std::round(static_cast<double>(real/divisor)) - 1); ++i)
		{
			std::cout << "*" << " " ;
		}
		std::cout << "\n";
	}

    //return 0;
}
closed account (48T7M4Gy)
there is integer division going on in your code and you're not rounding to the nearest '000:
Thanks - wow, it is indeed integer division, I always wondered what that slash meant. And as for rounding, the snippet I suggest duplicates the sample barchart asterisk configuration.The problem statement is ambiguous. 'Each thousand' conflicts with 'to nearest thousand' so I amde the decision to go with the sample output.
kemort - you're right, if rounding to nearest '000 is not required then integer division should be fine
closed account (48T7M4Gy)
Of course, gunner, if we round with more precision without getting into a dreaded floor ceiling tiff I remember some time ago:

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
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

int main()
{
    ifstream inputFile;		// File stream object
    inputFile.open("Mitra.txt");
    
    int year, population;
    
    while (inputFile >> year >> population)
    {
        cout << "For year: " << year << " ";
        
        for (int i = 0; i < (population + 500) / 1000; i++)
        {
            cout << "*";
        }
        cout << endl;
    }
    
    return 0;
}
which gives this output

For year: 1890 
For year: 1891 
For year: 1892 
For year: 1893 *
For year: 1894 *
For year: 1895 *
For year: 1896 *
For year: 1897 *
For year: 1900 **
For year: 1920 *****
For year: 1940 ******
For year: 1960 ******
For year: 1980 ********
For year: 2000 ***************
Program ended with exit code: 0


for this input
1890 0
1891 1
1892 499
1893 500
1894 501
1895 999
1896 1000
1897 1001
1900 2230
1920 4899
1940 5783
1960 6466
1980 8222
2000 15248
So I am trying to understand the logic in regards so printing out the stars, but I totally understand the logic in regards why we should use the file. Because if the year changes to something like 1920, 1930, that's the reason we use it so it's not always constant.

Anyways my main issue is understand the code presented by @dhayden and @kemort. It seems what @dhayden says that for the first population it reads in 2230. The "i" starts at 1000, so technically it's "i" starting at 1000, which is less than equel to 2230, incrementing by 1000 so that's how it's printing out 2 stars. This would be the same concept with the rest of the data in regards to the population. I am not understanding why my original code did not print the right amount of stars?

I started at "i = 0;" then i <= 2230; then which increments by 1000. Shouldn't this print at 2 stars technically? That's what is throwing me off.

I understand what @kemort suggested to in regards to his code. Saying "i < 1", and not only that, but population divided by 1000. For example, population starting at zero, reads in i <= 2230 / 1000, then starts to print out that many stars. Hopefully I got that concept right. So it would be printing out 2 stars because of 2230/1000 = 2, starting from 1 and 2.
closed account (48T7M4Gy)
@Bayan

Perhaps with longer variable names?
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 <fstream>

using namespace std;

int main()
{
    ifstream inputFile;		// File stream object
    inputFile.open("Mitra.txt");
    
    int year, population;
    int number_of_thousands = 0; // <--
    
    while (inputFile >> year >> population)
    {
        number_of_thousands = (population + 500)/1000;
        
        cout << "For year: " << year << " ";
        
        for (int number_of_asterisks = 0; number_of_asterisks < number_of_thousands; number_of_asterisks++)
        {
            cout << "*";
        }
        cout << endl;
    }
    
    return 0;
}
Got it now, thanks!
I started at "i = 0;" then i <= 2230; then which increments by 1000. Shouldn't this print at 2 stars technically? That's what is throwing me off.

On the first pass through your loop, i==0 and it prints a star.
On the next pass, i==1000 and it prints a star
On the next pass i==2000 and it prints a star
On the next pass i==3000 and the loop exits.

In total it prints 3 stars.
Topic archived. No new replies allowed.