Trying to get the Numbers to input and do the calculation correctly

The equation isn't coming outright. It keeps telling me 11% in my our program. I'm brand new to C++ so I know I must be doing something simple wrong. But I just don't know what, I just need the program to read two numbers from a .txt file and get a percentage. I also need that to round to a whole number and output the description with it. Any suggestions would be welcome. Thanks.

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
58
59
60
61
62
 #include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
#include <fstream>

using namespace std;


//Global declarations: Constants and type definitions only -- no variables


//Function prototypes

int main()
{
	//In cout statement below SUBSTITUTE  your name and lab number
	cout <<  << endl << endl;

	//Variable declarations
	double score;
	double total;
	double grade;
	string ScoreandTotal;
	string description; 

	ifstream inFile;


	inFile.open(ScoreandTotal);
	

		//Program Logic 

	inFile >> score >> total;

	grade = score / total;

		if (grade >= 90)
			description = "Excellent";
		else if (grade >= 80)
			description = "Well Done";
		else if (grade >= 70)
			description = "Good";
		else if (grade >= 60)
			description = "Need Improvement";
		else (grade < 59.9);
			description = "Fail";

		cout << "Grade" << grade << setprecision(0) << fixed << round(grade) << "%" <<
		setprecision(5) << fixed << "" << description << endl;;


	inFile.close();

	

	//Closing program statements

	system("pause");

	return 0;
Hello heart1210,

I can not test your program because I do not have the input file that you are using. Anything I do will not math what you are using.

On line 30 you open a file, but how do you know it is open?

Please provide the input file that you are using.

Andy
Andy,
I'm using a . text file with "85.56 100" Those are the only two numbers in the file.

That was a question I had I added a inFile.fail loop to test that and it keeps returning as an error. So I need to know why the file isnt being opened. Like I said I'm new to this so anyhelp with Help. lol
Hello heart1210,

While I was waiting I made these changes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const string ScoreandTotal{ "Grades.txt" };  // <--- Needs a file name
    
ifstream inFile(ScoreandTotal);

if (!inFile)
{
    std::cout << "\n File " << std::quoted(ScoreandTotal) << " did not open" << std::endl;

    return 1;
}

grade = (score / total) * 100.0;

if (grade >= 90.0)
    description = "Excellent";
else if (grade >= 80.0)

else if (grade < 59.9)  // <--- Needs the if.

cout << "Grade " << grade << "  " << setprecision(0) << fixed << round(grade) << "%" <<
        setprecision(5) << fixed << " " << description << "\n\n";

In the "cout" the changes are minor. Just added some spaces.

lines 5 - 10 check if the file is opened and ready to use. Without this the program could continue without being able to read the file. This is a must for any input or output file.

Prefer to use '\n' in place of most "endl"s.

Andy
Hello heart1210,

That was a question I had I added a inFile.fail loop to test that and it keeps returning as an error.


If the file does not open and the file name is spelled correctly I would look at where the file is stored.

When you just use a file name, no path, the program will look in the current working directory for the file. If you are using an IDE to work with your program the current working is usually the same place that the ".cpp" and ".h" or ".hpp" files are stored.

If you compile and or run the program from a different directory the current working directory will be different.

Andy
Andy,
Thanks The file was located in the wrong directory and that seemed to fix the problem.

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
	int x;
	int y;
	double grade;
	string{ "Text.txt" };
	string description;
	ifstream inFile;



	//Program Logic 
	{
		inFile.open("Text.txt");

		if (!inFile)
		{
			std::cout << "\n File " << " did not open" << std::endl;

			return 1;
		}
		if (!inFile) {

			inFile >> x >> y;
			grade = x / y * 100;

			if (grade >= 90)
				description = "Excellent";
			else if (grade >= 80)
				description = "Well Done";
			else if (grade >= 70)
				description = "Good";
			else if (grade >= 60)
				description = "Need Improvement";
			else (grade < 59.9);
			description = "Fail";

			cout << grade << fixed << round(grade) << "%"
				<< setprecision(5) << fixed << " " << description << endl;;

		}
	
	}
	inFile.close();

	

	//Closing program statements

	system("pause");

	return 0;


Only Issue now is that I don't get anything with i run the debugger just
Press any button to continue.

I'm curious now what to do.
Hello heart1210,

You do not need the if statement at line 20. Also it is working the opposit of what you are thinking, so it bypasses the if statement and ends the program.

What you could do is change the if statement to: while (inFile >> score >> total) and you could process a file with more than 1 line with the while condition becoming false and ending the loop when there is nothing left to read and the "eof" bit is set. This way it will not matter if there is 1 line or 100 lines.

Andy
Hello heart1210,

Using the while that I mentioned I put this line above the while loop:
std::cout << fixed; // <--- Only needs done once.

Then I ended up changing the "cout" statement
cout << "Grade " << std::setprecision(2) << grade << " " << setprecision(0) << round(grade) << "%" << " " << description << "\n\n";
The "setprecision(5)" did not relate to anything until the second time through the loop where the output "grade" was changed.

This produced the output of:

Grade 85.56  86% Well Done

Grade 90.25  90% Excellent

Grade 71.00  71% Good

Grade 65.50  66% Need Improvement

Grade 45.00  45% Fail

Grade 59.80  60% Fail

Press any key to continue . . .



Andy
Hello heart1210,

Let me cover some things that you may find helpful in the future.

On the main page of the forum the first post http://www.cplusplus.com/forum/beginner/1/ is worth reading and more than once.

I am not sure where I first read it, but when you make your first post it helps everyone to mention whet IDE/compiler you are using.

If you are asking about something that comes from a school assignment it is best to post the instructions that you were given and not what you think they mean because someone else may see a question that you may need to have answered or that you may have to clarify.

If you do not know what is wrong with your code then you will not know what to fix or understand some of the suggestions that you are given.

I will refer to the last revised code that you posted.

I realize that these are your changes, but it is always best to post enough code that can be compiled and tested. It is easy enough for you to copy and paste, so do not make others fill in what you missed. It is also possible that something may be seen in what you left out that needs a mention.

Looking at the code:
Lines 1 and 2 were better in your first code. Defining these variables as "int"s is a step backwards. As you read the file the first number (85.56) is a floating point number, i.e., a double, that you are storing in an "int". This will work, but since an "int" only stores whole numbers the decimal part will be dropped. Not quite what you want.

The next problem is the variable names. In your first code not only are the variables defined with the correct type they have better names than "x" and "y". "score" is a good name, but "total" is misleading. It makes me thing that you are keeping a running total of something. For this variable "totalPoints" or pointsTotal" would work better.

For your first 3 variable it is always a good idea to initialize the variables. From C++11 on you have the uniform initializer, the {}s, empty the compiler will choose the best value to initialize the variable based on its type. The added advantage is that you can put a value between the {}s.

"strings", "vectors" and other containers are empty when defined and do not need to be initialized unless you want to give it a starting value.

Line 4 is a good start, but you forgot the variable name. If you tried to compile this I would expect an error.

The way you have used lines 6 and 12 is fine. It works. A suggestion or alternative that I normally use:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Line 3 will create an object of "ifstream" and what is in the () will use the overloaded ctor to open the file at the same time. This sames you a line of code.


const std::string IN_FILE_NAME{ "" };  // <--- Put File name here.

std::ifstream inFile(IN_FILE_NAME);

if (!inFile)
{
	std::cerr << "\n File " << std::quoted(IN_FILE_NAME) << " did not open" << std::endl;
        //std::cerr << "\n File \"" << IN_FILE_NAME << "\" did not open." << std::endl;

    return 1;
}

If you are not comfortable with the "std::quoted" the commented line will do the same thing. "std::quoted" comes from the "iomanip" header file and unless someone tells you about it or you see it in use you may never know about it. It is handy, but not always necessary.

At line 11 and at line 42 the {}s are not necessary and could be potential problem. If you were to define a variable inside those {}s it would local to that block and would be destroyed at the ending }. So if you intended to use it outside of that block you could not because it is no longer available.

Between lines 19 and 20 you need a blank line.

Line 20 is not working the way that you may be thinking. Given an if statement, a while condition or the middle part of a for loop what is between the () or the (; ;) is something that is evaluated to either (0) zero or something other than 0. This is converted to a bool variable with (0) meaning false or 1 meaning true. So in this case the (inFile) would evaluate to true and the use of (!) would make it false.

Even if you fix line 20 there is still no need for it because the is no loop back to use it a second time. Changing line 20 to a while loop as I showed you would make better use of the code block.

Line 24 works as is, but sometimes it is better to use () to show your intent or to make sure what is done first. grade = (score / total) * 100.0;.

In C++ there is no "else if" statement. Most times it is written else if (grade >= 80) and this works just fine. The 1 problem you do have is else (grade < 59.9); "else" is not used with anything in (), so this either needs to be an "else if" or loose the () and everything in them. Also ending this line with a (;) makes the next line not part of "if/else if/else" chain, so the last instruction is to set description = "Fail". Therefor it will not matter what the score is it will always say "Fail".

Line 37 your "cout" statement.
Normally I would put this near the top of the program:
 
std::cout << std::fixed << std::showpoint << std::setprecision(2);;  // <--- Only needs done once. 

All 3 are done at once and will stay that way until changed.

In your code the "fixed" is used twice the first one could be useful, but it is in the wrong place. The second is not needed. Since "fixed" comes after "grade" it has no affect on "grade" which could be output in scientific notation, which is the default for displaying a "double" or "float". In a loop the 2nd time around that would be different.
The next part: setprecision(5) << fixed << " " << description << endl;. The "setprecision" and "fixed" have no affect on output of a "std::string", They only work on "double"s. In a loop the 2nd time around "grade" would now output with 5 decimal places and then "round(grade)" would also have 5 decimal places.

You had a better start with your original code. I eventually came to this:
 
cout << "Grade " << std::setprecision(2) << grade << "  " << setprecision(0) << round(grade) << "%" << " " << description << "\n\n";

The "setprecision(0)" will not print any decimal places, but will print the decimal point. I would revise to this: std::cout << std::fixed;, what should be near the beginning of the code. The default value is "noshowpoint" and when you say "std::setprecision(2)" it will print ".00" because you told it to print 2 decimal places. Then when you say "setprecision(0)" before "round(grade)" it will print the whole number and no decimal point.

Line 43. Closing the file stream may be good form, but is not necessary as the dtor of the class will close the file and destroy the variable before the function looses scope. Or in this case before the program ends.

Last is the "return 0;". Again good form, but no longer a requirement sa the program will return (0) zero unless you tell it otherwise.

Andy
Andy,
Thank you for the information and the help. I will take it all to knowledge.

I have the code working now the way it needs to. Thanks again!!!
Topic archived. No new replies allowed.