C++: while/if and return problem

Dec 6, 2020 at 1:02pm
Hi,

I have a struct. User can decide do he want to print so there is
1
2
cout << endl << "Want to print? (1. yes, 2. no, 3. quit) ";
cin >> i.Print;


Problem is where I put that while loop. I have a main and sub program. In sub program I ask the info and main program prints it.

So I have this loop in sub program:

1
2
3
4
5
6
7
8
9
10
	while (i.Print != 3)
		if (i.Print == 1)
		{
			return i;
		}
		else if (i.Print == 2)
		{
			cout << "Program has stoped."
		}
	cout << "You quit the program.";


But if user puts 2 (=no printing) it goes forever loop. I think this should be in main program but how can I move the value of i from sub to main?

I really hopes someone understands, sorry about bad english. I can show the whole code if it helps.
Dec 6, 2020 at 1:44pm
Hello Scorpia,

while (i.Print != 3). What is the value of "i,Print"?

If you reach the else/if statement where does the value of "i,Print" change?

With out enough code to compile and test it is hard to say where the problem starts.

Andy
Dec 6, 2020 at 1:49pm
User define the value of i.Print, it is either 1, 2 or 3. Its a pretty long code, maybe I can put it to pastebin or something? Its over 160 lines. :D
Dec 6, 2020 at 1:52pm
Hello Scorpia,

Should fit here. I have seen 250+ lines posted here.

Andy
Dec 6, 2020 at 1:57pm
Okey, here we go. :) And there is some finnish in.

And I like to hear some feedback about the code if somebody has a moment.

 
Last edited on Dec 7, 2020 at 5:11am
Dec 6, 2020 at 2:06pm
Hello Scorpia,

First off you should use "<cmath>" not "<math.h>". "math.h" is a C header file and "cmath" is the C++ version. Also I have not seen any reason to need "<cmath>" in the program. Check http://www.cplusplus.com/reference/cmath/ to see what is available in "cmath". Then again I may have missed its need for now.

Prefer to use "double"s over "float"s.

I need a few minutes to go over the code.

Andy
Dec 6, 2020 at 3:06pm
Oh right, I used that library when I have a few lines where it was needed but it's deleted already. So i delete that also. Thanks!
Dec 6, 2020 at 6:09pm
Hello Scorpia,

Sorry about the delay. Between translating and testing this took longer than I thought.

Prefer to use the new line, ("\n"), over the "endl". "endl" is a function that takes time and the more you have the more time you will waste. At some point you may notice the program running slower.

In the beginning I changed these parts:
1
2
3
4
5
6
7
#include <iostream>
#include <iomanip>
#include <limits>
#include <string>
//#include <cmath>  // <--- Proper file, but not needed.

void studentGrade(Student& student);  // <--- Changed. 
. The function now makes better use of what you have.

In "main":
1
2
3
4
for (int number = 0; number < count; number++)
{
    studentGrade(student[number]);
}

Here you are sending 1 element to the function to use.

This is the translated version, but it is to show more the concept of what I did.
1
2
3
4
5
6
7
8
9
10
11
12
for (int number2 = 0; number2 < count; number2++)
{
    if (student[number2].Print == 1)
        cout << '\n'
            << "Student number: " << (number2 + 1) << ". information." << '\n'
            << "First name: " << student[number2].FirstName << '\n'
            << "Surname: " << student[number2].LastName << '\n'
            << "Rating of weekly exercises: " << student[number2].Grade << '\n'
            << "Grade assignment: " << student[number2].PracticeW << '\n' << '\n'
            << "Overall grade: " << student[number2].FirstName << ": " << student[number2].TotalGrade << ", rounded "
            << setprecision(1) << student[number2].TotalGrade << '\n';
}

The if statement is to allow something to display unless the functions choise was 2 or 3.

I put this after the above for loop because it works better:
1
2
3
4
5
std::cout << "\n\n" << "Press enter to close the program. ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
std::cin.get();

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

Line 2 may not always be needed.

For the function, the parts I worked on:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void studentGrade(Student& student)
{
    // Enter the data
    //Student student;  // <--- No longer needed.

    //cout << "1. Enter the student's first name: ";
    //cin >> student.FirstName;
    student.FirstName = "Stan"; // <--- Used for testing. Comment or remove when finished.
    cout << "1. Enter the student's first name: " << student.FirstName << '\n'; // <--- Used for testing. Comment or remove when finished.

cout << "\nThe total grade is as follows: weekly exercises " << student.Setting << "% and assignment " << 100 - student.Setting << "%." << '\n';

cout << "\nPrint data? (1. yes, 2. no, 3. interrupt): ";


Lines 6 - 9 is a little trick to not have to enter something each time the program runs, but it works best when int count{ 1 }; in "main". Once you know that the input is working it comes in very handy.

Line 11 was adding some spaces and using the "\n" instead of the "endl"s.

Line 13 I left where you originally had it, but did comment the following "cin". At least until I can get the while condition working better.

This is what I ended up with for the while loop:
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
while (cin >> student.Print && !std::cin || (student.Print > 1 || student.Print < 4))
{
    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 (student.Print == 1)
    {
        Grade1 = (student.Setting * Grade) / 100.0;
        Grade2 = ((100 - student.Setting) * student.PracticeW) / 100.0;

        TotalGrade = Grade1 + Grade2;

        student.TotalGrade = TotalGrade;

        return;
    }
    else if (student.Print == 2)
    {
        cout << "\n     Data will not be printed. The program will be aborted.\n\n";
        break;
    }
    else if (student.Print == 3)
    {
        std::cout << "\n   Program interrupted.\n\n";
        break;
    }
    else
    {
        std::cerr << "\n     Invalid Choice! try again.\n\nPrint data ? (1. yes, 2. no, 3. interrupt) : ";
    }
}


These changes appear to work for now, but there are some other things I want to try.

I would first get it working for 1 student then try for 2 or 3.

Andy
Dec 6, 2020 at 6:34pm
Hello Scorpia,

After a little testing I came to this for the while loop:
1
2
while (cout << "\nPrint data? (1. yes, 2. no, 3. interrupt): "  &&
           cin >> student.Print && !std::cin || (student.Print > 0 || student.Print < 4))


Andy
Dec 7, 2020 at 5:10am
Oh gosh what a angel we have here! :)
Thank you so much, this means a lot for me as a beginner. Good notes, clear and easy to understand. I try these and make my code even better. Thank you!

I have a another question about alphabetical order in printing but I think I should do new topic?
Last edited on Dec 7, 2020 at 5:30am
Dec 7, 2020 at 5:56pm
Missing {} in the while

If there are no parentheses the loop will do one line, or not at all if the condition is false. At other than 1 it spins endlessly.
You dont need { in if and if else.
Last edited on Dec 7, 2020 at 7:09pm
Topic archived. No new replies allowed.