I'm attempting to read a number from a text file referring for yearly population and have one asterisk for every one thousand residents by year. When I run the program, asterisks run indefinitely and I can't figure out how to run only one per 1000 residents.
#include <iomanip>
#include <fstream>
#include <iostream>
#include <string>
using std::endl;
using std::ifstream;
//start of program
int main ()
{
ifstream inFile;
int year, population, num, i;
//includes the popluation.txt file
inFile.open("population.txt");
if (!inFile) {
cout << "Unable to open file";
exit(1); // terminate with error
}
while(inFile)
{
// inFile >> year >> population;
cout << year << endl;; //process data
inFile >> year >> population; // next line
}
while(population >= 1000)
{
for (population = 0; population < num; i)
cout << "*" << endl;
population ;
}
inFile.close();
return 0;
}
population.txt
1900 2230
1920 4532
1940 5783
1960 6466
1980 8222
2000 10348
CodePudding user response:
This is one situation where it is very important to remember the Golden Rule Of Computer Programming: "Your computer always does exactly what you tell it to do, instead of what you want it to do".
So, let's explore what you told your computer to do:
while(inFile)
{
You told your computer to execute the statements in the while loop as long as inFile
is in a valid state. Ok, so what did you tell your computer to do, as long as inFile
is in a valid state?
cout << year << endl;; //process data
inFile >> year >> population; // next line
You told your computer to print what's in the year
, then read from inFile
into year
and population
.
So, as long as inFile
is in a valid state, you'll read from the file into year
and population
. And do absolutely nothing else, whatsoever.
Is that what you wanted your computer to do? Based on what you described, of course not. You wanted your computer to do something for every year
and population
. But you told your computer to do something else: read the entire file, each time reading into year
and population
. So that's what your computer will do, and it will not do anything else until this part is done.
Additionally, you might've noticed that you told your computer to show what's in year
before even reading anything into it. After all, you told your computer: show what's in year
before continuing to read from inFile
. So, before even reading anything into year
you told your computer to show what's in year
. That, of course, doesn't make much sense but that's what you told your computer to do.
But, after telling your computer to do all of this, what did you tell your ocmputer to do, after reaching the end of the file?
while(population >= 1000)
Ok, you told your computer to do all of the following, as long as population
is 1000 or more.
for (population = 0; population < num; i)
cout << "*" << endl;
Start with population
being 0, and increase i
as long as population
is less than num
?
What is num
? There's nothing in the shown code that sets num
to anything. So, what is your computer supposed to do, here? What is i
? You did not tell your computer, beforehand, what is i
, either. So, your computer literally has no idea, whatsoever, what your computer should do. This is what's called, in C , "undefined behavior". Your computer just throws up its hand, and just does whatever it wants, like printing infinite number of asterisks, at this point.
I can't figure out how to run only one per 1000 residents.
That's simple: just tell your computer exactly what it should do. Start by writing down, on a piece of paper, in plain English, what you want your computer to do, exactly. For example:
Attempt to read the next year, and the population from the file. If this fails you're done, that's it.
Show the year that was read, and initialize a counter to 0.
Is the counter less than the population size? If so, print an asterisk, add 1000 to the counter, and repeat.
Print a newline, the end of the line.
So, after writing all of that, simply take the above and translate it directly into C ! That's it! You told exactly what you wanted your computer to do!
CodePudding user response:
Maybe you could use the std::string
fill constructor to repeat the astrixes appropriately:
#include <iostream>
#include <fstream>
int main() {
std::ifstream in_file;
in_file.open("population.txt");
if (!in_file) {
std::cout << "Unable to open file";
exit(1);
}
int year, population;
while (in_file >> year >> population) {
std::cout << year << ": " << std::string(population / 1000, '*') << " (" << population << ")" << '\n';
}
in_file.close();
return 0;
}
Output:
1900: ** (2230)
1920: **** (4532)
1940: ***** (5783)
1960: ****** (6466)
1980: ******** (8222)
2000: ********** (10348)
CodePudding user response:
You can use brute-force with a simple for
loop:
int quantity = population / 1000;
for (int i = 0; i < quantity; i)
{
std::cout << "*";
}
std::cout << "\n";
The above code uses math to determine the quantity of asterisks. The loop prints the asterisks according to the quantity.