Computer Science Canada

For Loop Trouble . . .

Author:  jamonathin [ Tue Apr 26, 2005 11:31 am ]
Post subject:  For Loop Trouble . . .

Hey, i was trying to make just some simple multiplying program, where it asks to input two numbers, and gives the sum of them. After I enter the first number, the program finishes. Any ideas?
code:
#include <iostream>
using namespace std;

int numb,numb2,result;
int main (){cout <<"Enter a number";cin>>numb;return 0;}
int main2 (){cout<<"Enter another number to multiply it by";cin>>numb2;return 0;}
int calculate (){cout<<numb<< "Multplied By"<<numb2<<"Is Equal To"<<numb * numb2;cin>>result;return 0;}

Author:  wtd [ Tue Apr 26, 2005 11:55 am ]
Post subject: 

A few things:

  • The "main" function if your program's "entry point". It's where everything happens. Unless you call a "main2" function from within "main", the code in it won't be executed.
  • Don't declare global variables. Declare them as locals within the main function.
  • Use space.


c++:
#include <iostream>

int main()
{
   int n1, n2;
   std::cout << "Enter a number: ";
   std::cin >> n1;
   std::cout << "Enter another number: ";
   std::cin >> n2;
   
   int result = n1 * n2;

   std::cout << n1 << " * " << n2 << " = " << result;

   return 0;
}

Author:  jamonathin [ Tue Apr 26, 2005 1:29 pm ]
Post subject: 

Ok, thanks wtd, probabily makes more sense than mine (using std:: ). One quick question though, how do you make the code type C++ when you post? Confused

Author:  wtd [ Tue Apr 26, 2005 1:31 pm ]
Post subject: 

[syntax="cpp"][/syntax]

Author:  jamonathin [ Tue Apr 26, 2005 1:42 pm ]
Post subject: 

c++:
Thanks man

Author:  Andy [ Tue Apr 26, 2005 7:42 pm ]
Post subject: 

good one.. except he said cpp not c++

Author:  wtd [ Tue Apr 26, 2005 8:02 pm ]
Post subject: 

You can't use "c++" in the syntax tag. "cpp" gets turned into "c++".

Author:  jamonathin [ Wed Apr 27, 2005 8:40 am ]
Post subject: 

Hey, I have a new question now. I've been lookin through the Tutorials, and I've come accros some basic stuff, and I'm havin a little trouble with it, cuz I cant really understand what the error log wants me to do.
I tried out that "password program" and so i can do that, it just mixing stuff together, this is what i have
c++:
#include <iostream>
#include <string>

int main ()
{
    std::string password= "password",userword= "";
    int entry;
   
    std::cout<<"Enter The Password: ";
    std::cin>>userword;
   
    if (userword == password)
        std::cout<<"Access Granted";
        entry = 1;
    else
        std::cout<<"Access Denied";
        entry = 0;
       
    int wait;
    std::cin>>wait;
   
    return 0;
}
int calculator()
    int choice, n1, n2;
   
    if (entry == 1)
       std::cout<<"Welcome to Calculator!";
       std::cout<<"What Would Like To Do?";
       std::cout<<"1 - Add";
       std::cout<<"2 - Subtract";
       std::cout<<"3 - Multiply";
       std::cout<<"4 - Divide";
       std::cin>>choice;
       std::cout<<"Please Select Two Numbers. ";
       std::cin>>n1;
       std::cin>>n2;
       
       if (choice == 1)
          std::cout<<n1<<" + "<<n2<<" = "<<n1 + n2;
       if (choice == 2)
          std::cout<<n1<<" - "<<n2<<" = "<<n1 - n2;
       if (choice == 3)
          std::cout<<n1<<" * "<<n2<<" = "<<n1 * n2;
       if (choice == 4)
          std::cout<<n1<<" / "<<n2<<" = "<<n1 / n2;
         
       std::cin>>wait;
       
       return 0;
}

[ I tried to use wtd's spacing method Confused ]

Author:  Martin [ Wed Apr 27, 2005 10:04 am ]
Post subject: 

The problem that you are having is with your if statements.

In C++, you must inclose your if statements in code brackets like so:

c++:
if (statement)
{
     ...the code in here gets run if 'statement' is true...
}
else if (statement2)
{
     ...this code gets run if statement2 is true...
}


The exception to this is when you have a single line after the if statement, like so.

c++:
if (statement)
    cout << "Hello" << endl;


is the equivalent of

c++:
if (statement)
{
     cout << "Hello World" << endl;
}


If you wrote this, however, your output might not be what you expect:
c++:
if (statement)
     cout << "This line gets output if statement is true" << endl;
     cout << "This line gets executed regardless of whether or not statement is true" << endl;


The above code is equivalent to this:
c++:
if (statement)
{
     cout << "This line gets output if statement is true" << endl;
}
cout << "This line gets executed regardless of whether or not statement is true" << endl;

Author:  wtd [ Wed Apr 27, 2005 11:11 am ]
Post subject: 

First off, if "entry" is meant to be eiher 1 or 0 all the time, it sounds like a boolean value. In this case use a bool variable.

code:
bool entry;


and

code:
entry = true;


or

code:
entry = false;


Secondly, where you have:

c++:
       if (choice == 1)
          std::cout<<n1<<" + "<<n2<<" = "<<n1 + n2;
       if (choice == 2)
          std::cout<<n1<<" - "<<n2<<" = "<<n1 - n2;
       if (choice == 3)
          std::cout<<n1<<" * "<<n2<<" = "<<n1 * n2;
       if (choice == 4)
          std::cout<<n1<<" / "<<n2<<" = "<<n1 / n2;


You might more appropriately use "else if":

c++:
       if (choice == 1)
          std::cout<<n1<<" + "<<n2<<" = "<<n1 + n2;
       else if (choice == 2)
          std::cout<<n1<<" - "<<n2<<" = "<<n1 - n2;
       else if (choice == 3)
          std::cout<<n1<<" * "<<n2<<" = "<<n1 * n2;
       else if (choice == 4)
          std::cout<<n1<<" / "<<n2<<" = "<<n1 / n2;


To ensure that only one of these can be executed.

Or a switch statement.

c++:
switch (choice)
{
   case 1:
      std::cout << n1 << " + " << n2 << " = " << n1 + n2;
      break;
   case 2:
      std::cout << n1 << " - " << n2 << " = " << n1 - n2;
      break;
   case 3:
      std::cout << n1 << " * " << n2 << " = " << n1 * n2;
      break;
   case 4:
      std::cout << n1 << " / " << n2 << " = " << n1 / n2;
      break;
}

Author:  md [ Wed Apr 27, 2005 11:11 am ]
Post subject: 

Fisrt problem is that the second function is not called from the first, nor is it properly bracketed. Another problem, which is easiest to fix here is that you use a variable called entry in calculate, but you don't ever decalre it. Since it's obvious that you want entry to have the same value as entry in main, we'll make it a parameter that get's passed. The fix is to add an open brace after the function header (int calculate(...)), and add a varaible to the header:
c++:

    ...
int calculator(int entry)
{
    ....
}


Another small, problem is that you need to declare a function before you call it, so as it is the main function doesn't know about the existance of the calculate function, so if you try to call calculate from main you'll get an error.

Here's hte rearanged code with proper bracketing, and the calculate procedure moved before the main procedure:
c++:

#include <iostream>
#include <string>

int calculator(int entry)
{
    int choice, n1, n2;
   
    if (entry == 1)
    {
       std::cout<<"Welcome to Calculator!";
       std::cout<<"What Would Like To Do?";
       std::cout<<"1 - Add";
       std::cout<<"2 - Subtract";
       std::cout<<"3 - Multiply";
       std::cout<<"4 - Divide";
       std::cin>>choice;
       std::cout<<"Please Select Two Numbers. ";
       std::cin>>n1;
       std::cin>>n2;
       
       if (choice == 1)
          std::cout<<n1<<" + "<<n2<<" = "<<n1 + n2;
       if (choice == 2)
          std::cout<<n1<<" - "<<n2<<" = "<<n1 - n2;
       if (choice == 3)
          std::cout<<n1<<" * "<<n2<<" = "<<n1 * n2;
       if (choice == 4)
          std::cout<<n1<<" / "<<n2<<" = "<<n1 / n2;
         
       std::cin>>wait;
   }
       
   return 0;
}

int main ()
{
    std::string password= "password",userword= "";
    int entry;
   
    std::cout<<"Enter The Password: ";
    std::cin>>userword;
   
    if (userword == password)
    {
        std::cout<<"Access Granted";
        entry = 1;
    }
    else
    {
        std::cout<<"Access Denied";
        entry = 0;
    }
       
    int wait;
    std::cin>>wait;
   
    return 0;
}


Now, the next thing to change is really important: you don't call calculate from main, so it will never be run! From what I can guess you want the calculate code to be run only if the user inputs the correct password, so doing that we get:
c++:

    ...
int main ()
{
    std::string password= "password",userword= "";
    int entry;
   
    std::cout<<"Enter The Password: ";
    std::cin>>userword;
   
    if (userword == password)
    {
        std::cout<<"Access Granted";
        entry = 1;
        Calculate(entry);
    }
    else
    {
        std::cout<<"Access Denied";
        entry = 0;
    }
       
    int wait;
    std::cin>>wait;
   
    return 0;
}


Now the last thing we can do is simplify the program be removing any unessessary steps, such as checking entry; since we only call Calculate if the password is correct, entry will always be one, and thus the code in Calculate() will always be executed. From this we can get rid of entry all together, as well as the big if statement in Calculate():
c++:

#include <iostream>
#include <string>

int Calculate ()
{
    int choice, n1, n2;
 
   std::cout<<"Welcome to Calculator!";
   std::cout<<"What Would Like To Do?";
   std::cout<<"1 - Add";
   std::cout<<"2 - Subtract";
   std::cout<<"3 - Multiply";
   std::cout<<"4 - Divide";
   std::cin>>choice;
   std::cout<<"Please Select Two Numbers. ";
   std::cin>>n1;
   std::cin>>n2;
       
   if (choice == 1)
      std::cout<<n1<<" + "<<n2<<" = "<<n1 + n2;
   if (choice == 2)
      std::cout<<n1<<" - "<<n2<<" = "<<n1 - n2;
   if (choice == 3)
      std::cout<<n1<<" * "<<n2<<" = "<<n1 * n2;
   if (choice == 4)
      std::cout<<n1<<" / "<<n2<<" = "<<n1 / n2;
               
   return 0;
}

int main ()
{
    std::string password= "password", userword= "";
    int entry;
   
    std::cout<<"Enter The Password: ";
    std::cin>>userword;
   
    if (userword == password)
    {
        std::cout<<"Access Granted";
        Calculate();
    }
    else
        std::cout<<"Access Denied";
   
       
    int wait;
    std::cin>>wait;
   
    return 0;
}

** note that in this case the delay in calculate was unnessessary, as there is a delay in main.

Hope this helps clear up a little at least, if you have any questions just ask Smile

EDIT (Martin): Gah, learn how to program Cornflake. Fixed your code. Wink

Author:  jamonathin [ Wed Apr 27, 2005 11:37 am ]
Post subject: 

Wow thanks for all ur help guys. I don't have time right now to look through my program to fix all of my errors, but i will. And the reason i used so many ifs, was because i tried elsif and it didn't work, and i was like, wtf mayte? and yeah, but thanks guys.

Author:  Martin [ Wed Apr 27, 2005 12:27 pm ]
Post subject: 

In C++ it's else if, not elsif

Author:  wtd [ Wed Apr 27, 2005 4:34 pm ]
Post subject: 

It's always best to use braces ( { } ). Otherwise you can have confusion.

Also, though neither C nor C++ enforce the division, it's best to separate your code into functions and procedures. (Functions which return a value, and those which return main).

So, you'd have a procedure which reads the numbers from the user, a function/procedure which does the appropriate math, and a procedure which outputs the result.

A common way to handle this is with object-oriented programming. OOP involves grouping related pieces of data and the operations on that data, as well as inheritance and encapsulation.

So, let's look at a simple class for this purpose.

c++:
enum operation { ADD, SUB, MUL, DIV };

class basic_calculator
{
   private:
      int number1;
      int number2;
   protected:
      int result;
   public:
      basic_calculator();

      void read_number1(std::istream& in);
      void read_number2(std::istream& in);
      void do_math(operation o);

      int get_number1() const;
      int get_number2() const;
      int get_result() const;
};


I know... whoa! What's all of that?

Well, we start with an enum, which lists all of the possible operations. This is a measure we take to make our code robust. If we just accept an integer and said 1 for addition, 2 for subtraction, etc. we'd be eft with the case of what to do with 5 or 6 or any other number not covered. With this an operation can only be one of those options.

Next we declare our "basic_calculator" class. "number1", "number2" will be private, so that only functions in the basic_calculator class can access them. "result" will be protected, so that anything which inherits from basic_calculator has access to it.

The rest is public. These are all member functions, and they're just declarations of those functions. We will later define how they actually work.

First off is the constructor which sets up the initial state of the object's variables (number1, number2, and result). It takes no arguments.

Next are functions to read in the numbers. As an argument, these take an input stream to read from. Also in this section is a procedure which does the actual math and modifies "result". It takes, as an argument, an operation to perform.

Next we have accessors which can retrieve each of the values involved, without changing those values. Since nothing is changed, we can specify that it's ok to call these functions on a constant basic_calculator.

Now, we just have to implement those functions.

c++:
basic_calculator::basic_calculator()
: number1(0)
, number2(0)
, result(0)
{ }

void basic_calculator::read_number1(std::istream& in)
{
   in >> number1;
}

void basic_calculator::read_number2(std::istream& in)
{
   in >> number2;
}

void basic_calculator::do_math(operation o)
{
   switch (o)
   {
      case ADD:
         result = number1 + number2;
         break;
      case SUB:
         result = number1 - number2;
         break;
      case MUL:
         result = number1 * number2;
         break;
      case DIV:
         result = number1 / number2;
         break;
   }
}

int basic_calculator::get_number1() const
{
   return number1;
}

int basic_calculator::get_number2() const
{
   return number2;
}

int basic_calculator::get_result() const
{
   return result;
}


Now, where do we go from here?

Well, what if we want floating point results? We'd have to create a whole other calculator class, right? Wrong. We can use templates to make the basic_calculator class "generic".

c++:
enum operation { ADD, SUB, MUL, DIV };

template <typename _t>
class basic_calculator
{
   private:
      _t number1;
      _t number2;
   protected:
      _t result;
   public:
      basic_calculator();

      void read_number1(std::istream& in);
      void read_number2(std::istream& in);
      void do_math(operation o);

      _t get_number1() const;
      _t get_number2() const;
      _t get_result() const;
};


c++:
template <typename _t>
basic_calculator<_t>::basic_calculator()
: number1(0)
, number2(0)
, result(0)
{ }

template <typename _t>
void basic_calculator<_t>::read_number1(std::istream& in)
{
   in >> number1;
}

template <typename _t>
void basic_calculator<_t>::read_number2(std::istream& in)
{
   in >> number2;
}

template <typename _t>
void basic_calculator<_t>::do_math(operation o)
{
   switch (o)
   {
      case ADD:
         result = number1 + number2;
         break;
      case SUB:
         result = number1 - number2;
         break;
      case MUL:
         result = number1 * number2;
         break;
      case DIV:
         result = number1 / number2;
         break;
   }
}

template <typename _t>
int basic_calculator<_t>::get_number1() const
{
   return number1;
}

template <typename _t>
int basic_calculator<_t>::get_number2() const
{
   return number2;
}

template <typename _t>
int basic_calculator<_t>::get_result() const
{
   return result;
}


And now to show a couple of uses of this:

c++:
int main()
{
   basic_calculator<int> bci;
   basic_calculator<double> bcd;

   bci.read_number1(std::cin);
   bci.read_number2(std::cin);
   bci.do_math(ADD);
   
   std::cout << bci.get_result() << std::endl;
   
   bcd.read_number1(std::cin);
   bcdi.read_number2(std::cin);
   bcd.do_math(DIV);
   
   std::cout << bcd.get_result() << std::endl;

   return 0;
}

Author:  jamonathin [ Thu Apr 28, 2005 7:44 am ]
Post subject: 

That's some crazy stuff, but you did a good job explaining it. Smile

Author:  Martin [ Thu Apr 28, 2005 8:35 am ]
Post subject: 

Just take it slow. C++ has a pretty steep learning curve, but it'll all make sense eventually.

Author:  jamonathin [ Thu Apr 28, 2005 8:46 am ]
Post subject: 

I've been reading through all of this, and for cornflakes/martin's method, how do you go from the second part to teh first part. I mean, how do you skip the calculator, and jump right to main?

And for wtd, I pretty much understand it, Its just I cant get it to run, I added the
c++:
#include <iostream>
#include <string> 
But are there any others I'm missing?

I'm tryin to take it slow, but i just recently realized how far behind I am programming wise, [ lol all i know is turing ]. So that's why I'm really pushin this c++ for me.

Author:  Martin [ Thu Apr 28, 2005 9:05 am ]
Post subject: 

int main is the entry point for the program. Unlike turing which just begins from the top of the code and works its way down, a C++ program starts at the int main method. Calculate() is just a function that you can call.

c++:

#include <iostream>
using namespace std;

void somefunction ()
{
      cout << "This code never gets called\n";
}

int main ()
{
     cout << "Hello World\n";
     return 0;
}

void someotherfunction ()
{
      cout << "This code never gets called\n";
}


The output for this program will be "Hello World"

Author:  jamonathin [ Thu Apr 28, 2005 11:10 am ]
Post subject: 

ohhhhhhhhh, i thought main was like Calculator, just a word, ok thats makes more sense, thanks Nuty Eyes .

Author:  jamonathin [ Thu Apr 28, 2005 11:40 am ]
Post subject: 

I hope I'm not buggin you guys too much, if I am, just kick me or something.
I was looking through the tutorials, and Hacker Dan suggested to just redo some old turing programs into C++.
I found an example of a for loop in the tuts section, but I can't quite figure it out.
c++:
#include <iostream>

int main ()
{
    int n, t = 1;
   
    std::cout << "Enter Any Number.\n";
    std::cin >> n;
   
    for (int i = 1; int i < n; i++)
    {
        t *= i;
    }

    std::cout << "The Result Is " << t;
       
    int wait;
    std::cin >> wait;
       
    return 0;
}

Also, if anyone knows where a good help file is, (like Turing's F10), can ya tell me about it, cuz I dun wanna annoy you guys. Thanks Very Happy

EDIT: It's kinda wierd wtd and I posted on the same minute, but on his 2000th post! Head Bang

Author:  wtd [ Thu Apr 28, 2005 11:40 am ]
Post subject: 

Martin wrote:
int main is the entry point for the program. Unlike turing which just begins from the top of the code and works its way down, a C++ program starts at the int main method. Calculate() is just a function that you can call.

c++:
#include <iostream>
using namespace std;

void somefunction ()
{
      cout << "This code never gets called\n";
}


Martin, while technically correct, the more idiomatic C++ solution is not to use a literal newline, but rather std::endl.

c++:
#include <iostream>
using namespace std;

void somefunction ()
{
      cout << "This code never gets called" << endl;
}

Author:  wtd [ Thu Apr 28, 2005 11:44 am ]
Post subject: 

c++:
for (int i = 1; int i < n; i++)


This is your problem.

The first "int" is used to declare the variable "i". Subsequent uses of "i" do not require it. Corrected, it looks like:

c++:
for (int i = 1; i < n; i++)

Author:  jamonathin [ Thu Apr 28, 2005 11:52 am ]
Post subject: 

Something's still wrong though. In Turing, if I enter 4, i get 24, but in this program, i get 6. This is my for loop in Turing.
Turing:
for i : 1 .. n
    t *= i
end for

Author:  wtd [ Thu Apr 28, 2005 11:57 am ]
Post subject: 

In your Turing loop, you say "loop from 1 to n". In the C++ loop you're saying "loop from i = 1 while i is less than n, incremeneting i by one each time".

Thus the loop goes from 1 to 3. To change this, you need to use the less than or equals operator. I'm just using a bit of a different initialization syntax for "i", and I'm using the prefix increment operator.

c++:
for (int i(n); i <= n; ++i)

Author:  Martin [ Thu Apr 28, 2005 12:18 pm ]
Post subject: 

it should be int i (1), not (n).

Author:  wtd [ Thu Apr 28, 2005 12:25 pm ]
Post subject: 

Ah yes.

Author:  Martin [ Thu Apr 28, 2005 12:28 pm ]
Post subject: 

Got your back Wink

Author:  wtd [ Thu Apr 28, 2005 12:38 pm ]
Post subject: 

Martin wrote:
Got your back Wink


That's what I'm afraid of. Wink

Author:  jamonathin [ Thu Apr 28, 2005 12:48 pm ]
Post subject: 

lol . . . works good guys, thanks Smile

Author:  wtd [ Thu Apr 28, 2005 12:56 pm ]
Post subject: 

Congrats on accidentally implementing a factorial function. Now you need only embrace the zen of:

Haskell:
factorial = product . enumFromTo 1


Smile


: