Can anyone help me with a C++ program?

chibicitiberiu

New Member
Hello everyone.
I'm new to these forums.

Now about my program, I compiled it with MS Visual Studio 6.0 on an older computer. It's a console application. This is the source code:

Code:
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<conio.h>
using namespace std;

int rand_0toN1(int n);

int main()
{

    // declaration of the variables
    int questions, limit, a, b, op, result, final=0;

    // set the random seed for the random function
    srand(time(NULL));

    // get number of questinons and limit
    cout<<endl<<"How many questions should be asked: ";cin>>questions;
    cout<<"What should be the maximum number allowed: ";cin>>limit;

    for(int i=1;i<=questions;i++)
    {
        op=rand_0toN1(4);
        if(op==0)
        {
            a=b=limit;
            while(a+b>limit)
            {
                a=rand_0toN1(limit+1);
                b=rand_0toN1(limit+1);
            }
            cout<<i<<") "<<a<<" + "<<b<<" = ";cin>>result;
            if(result == a+b)
                final++;
        }
        else if(op==1)
        {
            a=limit-1;
            b=limit;
            while(a<=b)
            {
                a=rand_0toN1(limit+1);
                b=rand_0toN1(limit+1);
            }
            cout<<i<<") "<<a<<" - "<<b<<" = ";cin>>result;
            if(result == a-b)
                final++;
        }
        else if(op==2)
        {
            a=b=limit;
            while(a*b>limit || a==0 || b==0 || a==1 || b==1)
            {
                a=rand_0toN1(limit+1);
                b=rand_0toN1(limit+1);
            }
            cout<<i<<") "<<a<<" x "<<b<<" = ";cin>>result;
            if(result == a*b)
                final++;
        }
        else if(op==3)
        {
            a=0; b=0;
            while(a==0 || b==0)
            {
                a=limit+1;
                b=limit+2;

                while(b>=a || a>limit || a%b!=0 || b==1)
                {
                    a=rand_0toN1(limit+1);
                    b=rand_0toN1(limit+1);
                }
            }

            cout<<i<<") "<<a<<" : "<<b<<" = ";cin>>result;
            if(result == a/b)
                final++;
        }
    }

        // displaying the final result
        cout<<"You answered correctly "<<final<<" questions out of "<<questions<<".";

        double percentage;
        percentage=(static_cast<double>(final)/static_cast<double>(questions))*100;
        cout<<"You answered correctly "<<int(percentage)<<"% .";

        // exiting
        cout<<endl<<endl<<"Press ENTER to exit.";
        getch();
        return 0;
}

int rand_0toN1(int n)
{
    return rand() % n;
}

This is what it should do:

Code:
How many questions should be asked: 5
What should be the maximum number allowed: 10
1) 6 + 3 = 9
2) 5 * 2 = 10
3) 5 - 3 = 3
4) 2 + 5 = 7
5) 8 / 4 = 2
You answered correctly 4 questions out of 5. You answered correctly 80% .

But, as always, problems occur. In my case, the problem is in this area of the program:
Code:
        else if(op==3)
        {
            a=0; b=0;
            while(a==0 || b==0)
            {
                a=limit+1;
                b=limit+2;

                while(b>=a || a>limit || a%b!=0 || b==1)
                {
                    a=rand_0toN1(limit+1);
                    b=rand_0toN1(limit+1);
                }
            }

            cout<<i<<") "<<a<<" : "<<b<<" = ";cin>>result;
            if(result == a/b)
                final++;
        }

The problem is that somehow the "b" variable is lost and the program returns an error that "Integer value can't be divided by zero". What should I do to fix this error? I tried replacing the first while with a goto and some "if"s, but no result:

Code:
        else if(op==3)
        {

    again:
                a=limit+1;
                b=limit+2;

                while(b>=a || a>limit || a%b!=0 || b==1)
                {
                    a=rand_0toN1(limit+1);
                    b=rand_0toN1(limit+1);
                }
            
            if(a==0) goto again;
            if(b==0) goto again;

            cout<<i<<") "<<a<<" : "<<b<<" = ";cin>>result;
            if(result == a/b)
                final++;
        }
As i said, this modification doesn't do anything.

Can anyone help me finding the error please? Any help is usefully.
 
Last edited:
And how is it going to help me solving this issue?

I don't need programs to debug this, i have visual studio and is enough for me. I need to find that error and fix it.
 
Feel free to ignore that spam, I'll try and get it removed.

I'm pretty sure your error is actually here not where you think it is:
Code:
int rand_0toN1(int n)
{
    return rand() % n;
}
Look at this code segment and think about what values it can return and you should see what's wrong.
 
I don't think that the rand_0toN1 function is problematic. It generates good numbers for all the operations (sum, difference, multiplication and ??division). In the division part somehow that "b" variable is lost (tried with a debugger).

Let me explain what that function (rand_0toN1) does: the rand() function generates a random number (and srand(time(NULL)) generates a random seed). The % (modulo) operator is used to get the rest from divisions. If you divide any number at "n", the rest will always be smaller or equal with "n-1". It shouldn't be problematic.
 
You are getting division by 0 errors are you not?

edit: Lets try looking at it this way:

7 % 7 = ?
 
Last edited:
That is right, 7%7=0; but this condition I put:
Code:
            if(a==0) goto again;
            if(b==0) goto again;
(or while(a==0 || b==0) )
should make it go back and find some other numbers until it passes, shouldn't it?


I think I found an idea which I will try tomorrow because now is late and I have to go to sleep. Like this:

Code:
else if(op == 3)
{
  while (1)
  {
    a=rand_0toN1(limit+1);
    b=rand_0toN1(limit+1);
    if (a!=0 && b!=0) break;
  }

  cout<<i<<") "<<a<<" : "<<b<<" = ";cin>>result;
            if(result == a/b)
                final++;
}

This will create an infinite loop until the program will find two variables that are different than zero.
 
Oh you're right you are checking for 0s, I kind of skimmed over that but your check is off. You want to make sure both are not 0 yes? Right now, you are using or which means if one is 0 and the other is not it will pass your check. That change you are thinking about doing should work but you should avoid goto's and breaks when you can.
Code:
while (a != 0 && b != 0) {
 --code--
}

edit: I'm having no end of trouble reading you code, it looks like your check should work.
Personally, I would just change the function I pointed to earlier.
Code:
int rand_0toN1(int n)
{
    return rand() % n + 1;
}
 
Last edited:
and not to forget about the other conditions the numbers have to pass:

Code:
else if(op == 3)
{
  while (1)
  {
    a=rand_0toN1(limit+1);
    b=rand_0toN1(limit+1);
    if (a!=0 && b!=0 && a<=limit && a%b==0 && b!=1) break;
  }

  cout<<i<<") "<<a<<" : "<<b<<" = ";cin>>result;
            if(result == a/b)
                final++;
}

Now, why should I add n+1 in the rand function when I set the entire program to work for n?

You are wrong. I have set the conditions at the beginning exactly in the opposite, and with || (or) because if the program will find that one condition is not respected it will continue the loop.

If this is going to work (I have to install MS Visual Studio on this machine because I used another one to compile this script, and that machine is very "outdated" (intel pentium II 400 MHz, 128 MB RAM, ATI 3D Rage 4MB Video card, Windows 2000 Pro.) and works slow.
 
Well here's the thing. Your way crashes occasionally, mine does not. I compiled your original code as well as a duplicate copy with my change and nothing else. In a dozen runs or so mine did not crash while the orignal code did. You can run with whatever version you want, if yours works power to you. My version simply prevents a 0 from ever being generated that way you don't get stuff like 9-0=?.
 
Yep the new latest code I shown worked; I also applied some more visual edits. This is the new source code and it works like charmed:

Code:
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<conio.h>
using namespace std;

int rand_0toN1(int n);

int options=false;

int main()
{

	// declaration of the variables
	int questions=10,newq, limit=1000000000,newl, a, b, op, result, final=0;

	// set the random seed for the random function
	srand(time(NULL));

	// Welcome screen
	int test;

	cout<<endl<<endl<<endl<<"          Welcome to The Maths Test.";
	cout<<endl<<endl<<endl<<"    Press Enter to start the test, O for options."<<endl<<endl;

	while(1)
	{
		test=getche();
		if(test==13) break;            //the Enter is #13
		else if (test==111)            //the O key is #111
		{
			options=true;
		}
	}

	// Options screen
	if (options)
	{
		cout<<endl<<endl<<"Options: ";
		cout<<endl<<"Select number of questions (0 for default): ";cin>>newq;
		if (newq) questions=newq;

		cout<<"Maximum number allowed (0 for default): ";cin>>newl;
		if (newl) limit=newl;

		cout<<endl<<endl<<endl<<endl;
	}


	// Questions
	for(int i=1;i<=questions;i++)
	{
		op=rand_0toN1(4);
		if(op==0)
		{
			while(1)
			{
				a=rand_0toN1(limit+1);
				b=rand_0toN1(limit+1);
				if (a+b<=limit) break;
			}
			cout<<i<<") "<<a<<" + "<<b<<" = ";cin>>result;
			if(result == a+b)
			{
				final++;
				cout<<"Correct."<<endl<<endl;
			}
			else cout<<"Wrong answer; the correct answer: "<<a+b<<endl<<endl; 
		}
		else if(op==1)
		{
			while(1)
			{
				a=rand_0toN1(limit+1);
				b=rand_0toN1(limit+1);
				if (a>=b) break;
			}
			cout<<i<<") "<<a<<" - "<<b<<" = ";cin>>result;
			if(result == a-b)
			{
				final++;
				cout<<"Correct."<<endl<<endl;
			}
			else cout<<"Wrong answer; the correct answer: "<<a-b<<endl<<endl; 

		}
		else if(op==2)
		{
			while(1)
			{
				a=rand_0toN1(limit+1);
				b=rand_0toN1(limit+1);
				if (a*b<=limit && a!=0 && b!=0 && a!=1 && b!=1) break;
			}
			cout<<i<<") "<<a<<" x "<<b<<" = ";cin>>result;
			if(result == a*b)
			{
				final++;
				cout<<"Correct."<<endl<<endl;
			}
			else cout<<"Wrong answer; the correct answer: "<<a*b<<endl<<endl; 

		}
		else if(op==3)
		{
			
			while(1)
			{
				a=rand_0toN1(limit+1);
				b=rand_0toN1(limit+1);
				if(a!=0 && b!=0 && b<a && a<=limit && a%b==0 && b!=1) break;
			}
				
			cout<<i<<") "<<a<<" : "<<b<<" = ";cin>>result;
			if(result == a/b)
			{
				final++;
				cout<<"Correct."<<endl<<endl;
			}
			else cout<<"Wrong answer; the correct answer: "<<a/b<<endl<<endl; 

		}
	}

		// displaying the final result
		cout<<endl<<"You answered correctly "<<final<<" questions out of "<<questions<<".";

		double percentage;
		percentage=(static_cast<double>(final)/static_cast<double>(questions))*100;
		cout<<"You answered correctly "<<int(percentage)<<"% .";

		// exiting
		cout<<endl<<endl<<"Press ENTER to exit.";
		getch();
		return 0;
}

int rand_0toN1(int n)
{
	return rand() % n;
}

Now a welcome screen is displayed, and the two questions about the number of questions and limit are now in the options which can be accessed pressing "o" in the welcome screen. Also, there are two default settings for these two variables.

And you are right, adding "+1" in the rand function will eliminate the "0" choice, but then you will never get sums, because the sum has the code "0"; also the function should be renamed, instead of "rand_0toN1" it should be "rand_1toN".
Same thing could be achieved if i would change the following lines everywhere they appear in the program:
Code:
From                                          To
a=rand0toN1(limit+1);        a=rand0toN1(limit)+1;
b=rand0toN1(limit+1);        b=rand0toN1(limit)+1;
 
Last edited:
And you are right, adding "+1" in the rand function will eliminate the "0" choice, but then you will never get sums, because the sum has the code "0"; also the function should be renamed, instead of "rand_0toN1" it should be "rand_1toN".
Same thing could be achieved if i would change the following lines everywhere they appear in the program:
True enough. I find it's a lot simplier to track changes and what might've broken something when instead of changing 10 parameters (or whatever) you just fix the function they are passing to. It's not always the solution either, there are times when it would actually be more work to fix everything else it really depends on the situation.
 
Back
Top