Checking for strings, and checking style...

When I input more then a single character program ends.

Page 1 of 1

7 Replies - 789 Views - Last Post: 23 January 2010 - 12:07 PM Rate Topic: -----

#1 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Checking for strings, and checking style...

Post icon  Posted 20 January 2010 - 02:47 PM

This is a program I am making for software methods. Basically it asks the user to pick a shape corresponding with 1,2, or 3. Then based on the shape the user is asked how big the radius, side, or height is.

The main problem I see currently is that when asking the user for the shape, if the user enters more than one character the program will end. If the user enters a single character the program will only run if they had entered a 1,2, or 3. Any help with this issue would be greatly appreciated.

Also, any tips on style or even the program itself are greatly appreciated, negative comments or positive.

 //This program asks the user for input and gives them the area of a shape.

#include <iostream>
using namespace std;

int main()
{
	char finished;
	do
	{
		if (!cin.good())
		{

			cin.clear();
			cin.sync();
			finished = 'y', 'Y';
			continue;
		}
	char choice;
	const double PI = 3.141592653589;
	double radius, side, height;
	cout << "This program will calculate the area of a circle, square, or triangle.\n";
	cout << "Input 1, 2, or 3 where '1' is a circle, '2' is a square, and '3' is a triangle. \n";
	cin >> choice;

	switch(choice)
	{
	case '1' :cout << "What is the radius?\n";
			  cin >> radius;
			  cout << "\n";
			  if(radius >= 0)
			  {
				cout << "The area of the circle is " << PI*radius*radius << " units squared.\n";
				cout << "Would you like to continue? Y/N \n";
			  }
			  else
			  {
				  cout << "\n";
			  }
		break;
	case '2' :cout << "What is the length of a side?\n";
			  cin >> side;
			  if(side >= 0)
			  {
				cout << "The area of the square is " << side*side << " units squared.\n";
				cout << "Would you like to continue? Y/N \n";
			  }
			  else
			  {
				  cout << " \n";
			  }
		break;
	case '3' :cout << "What is the height?\n";
			  cin >> height;
			  if(height >= 0)
			  {
				cout << "The area of the triangle is " << (height*height)/3 << " units squared.\n";
				cout << "Would you like to continue? Y/N \n";
			  }
			  else
			  {
				  cout << "Your input is invalid. Would you like to continue? Y/N \n";
			  }
		break;
	default : cout << "\n";
		break;
	}
	cout << "Your input is invalid. Would you like to continue? Y/N \n";
	cin >> finished;
}while (finished == 'y' || finished == 'Y');
	return 0;
}


Is This A Good Question/Topic? 0
  • +

Replies To: Checking for strings, and checking style...

#2 Paul-  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 61
  • View blog
  • Posts: 260
  • Joined: 11-December 09

Re: Checking for strings, and checking style...

Posted 20 January 2010 - 07:30 PM

One way to solve the problem is to read an entire string at a time, instead of a single character. Then test for the length of the string and accept only strings of length 1. The way the code is now, if you read one character at a time, but input 2 characters by mistake, the second character will be read into the "finished" variable.
Was This Post Helpful? 1
  • +
  • -

#3 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Checking for strings, and checking style...

Posted 20 January 2010 - 10:21 PM

if(radius >= 0)
{
	 cout << "The area of the circle is " << PI*radius*radius << " units squared.\n";
	 cout << "Would you like to continue? Y/N \n";
}


You forgot to use 'cin' there. You only print the message, if the user wants to continue. Correct way to do this will be:

cout << "Would you like to continue? Y/N \n";
cin >> finished;


And remove this:
cout << "Your input is invalid. Would you like to continue? Y/N \n";
cin >> finished;


This is usless. This line will be executed everytime, and you don't need it to...
Was This Post Helpful? 0
  • +
  • -

#4 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Checking for strings, and checking style...

Posted 21 January 2010 - 03:56 AM

You might like to see this revision of your code ...
(to glean some style hints and input validation tips)

See edited version below ...

This post has been edited by David W: 23 January 2010 - 12:27 PM

Was This Post Helpful? 1
  • +
  • -

#5 Riskinit  Icon User is offline

  • D.I.C Head

Reputation: 5
  • View blog
  • Posts: 157
  • Joined: 14-January 10

Re: Checking for strings, and checking style...

Posted 21 January 2010 - 08:20 AM

View Postsarmanu, on 20 Jan, 2010 - 09:21 PM, said:

if(radius >= 0)
{
	 cout << "The area of the circle is " << PI*radius*radius << " units squared.\n";
	 cout << "Would you like to continue? Y/N \n";
}


You forgot to use 'cin' there. You only print the message, if the user wants to continue. Correct way to do this will be:

cout << "Would you like to continue? Y/N \n";
cin >> finished;


And remove this:
cout << "Your input is invalid. Would you like to continue? Y/N \n";
cin >> finished;


This is usless. This line will be executed everytime, and you don't need it to...



Alright, I'll give it a try. Im still learning how to use loops effectively so I appreciate the help.
Was This Post Helpful? 0
  • +
  • -

#6 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Checking for strings, and checking style...

Posted 22 January 2010 - 07:02 AM

Re using loops in C++, you might like to see these ... (and the added comments) ...

Opps ... see edited version below

This post has been edited by David W: 23 January 2010 - 12:28 PM

Was This Post Helpful? 0
  • +
  • -

#7 charlejs  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 14
  • Joined: 19-January 10

Re: Checking for strings, and checking style...

Posted 23 January 2010 - 08:35 AM

Interesting I've seen that exact problem. Do you go to UC?
Was This Post Helpful? 0
  • +
  • -

#8 David W  Icon User is offline

  • DIC supporter
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,788
  • Joined: 20-September 08

Re: Checking for strings, and checking style...

Posted 23 January 2010 - 12:07 PM

This is an edited version ... here addARYs returns a double

double addARYs()

BTW ... years ago I started at UC ... i.e. University College at University of Toronto

// this demos a for( ... ) loop and a while loop ...
// note: these loops allow for the possibility to never enter the loop

// also  ... an example C++ solution of adding arrays of random integers
// Note: we don't really need the arrays here, since we could print and sum
// as we go ... with each new pair of random numbers ...
// But arrays are used here just to illustrate their use, if you really needed
// the values for some calculation ... like the standard deviation from the mean

#include <iostream>
#include <cstdlib> // re rand()
#include <ctime> // re srand()

// See a free Beginning C++ tutorial at:
// [url="http://developers-heaven.net/forum/index.php/topic,127.msg229.html#msg229"]http://developers-heaven.net/forum/index.p...229.html#msg229[/url]

using namespace std;

// a global constant
const int SIZE = 5; // change this and recompile with new 'compile time' value

// globals ... to keep the function call in addARYs simple
int ARY1[SIZE], ARY2[SIZE], ARYsum[SIZE];

bool enter() // defaults to yes ... enter ...
{
    cout << "Enter the main program loop (y/n) ? " << flush;
    int reply = cin.get();
    cin.sync();
    return reply != 'n' && reply != 'N';
}

// populate the arrays with random int's and sum
// and show the grand total ... and average value
double addARYs()
{
    int total = 0;
    // Note: if global SIZE preset to 0, loop never gets entered then ...
    // (but then will not compile ... if SIZE = 0 ... since zero division then.)
    for( int i=0; i<SIZE; ++i )
    {
        ARY1[i] = rand() % SIZE +1; // random numbers from 1..SIZE
        ARY2[i] = rand() % SIZE +1;
        ARYsum[i] = ARY1[i] + ARY2[i];
        total += ARYsum[i];
    }
    // note: '\t' is tab char ... in C/C++
    cout << "num1" << "\t+\t" << "num2" << "\t=\t" << "sum\n\n";

    for( int i=0; i<SIZE; ++i )
        cout << ARY1[i] << "\t+\t" << ARY2[i]
             << "\t=\t" << ARYsum[i] << endl;
    double avg = double(total)/(2*SIZE);
    cout << "\nThe grand total = " << total << " ..."
         << "\nThe average of all " << 2*SIZE << " values = "
         << avg << endl << endl;
    return avg;
}


int main()
{
    srand( time(0) ); // seed the random numbers with time ...
    
    // using a while loop here ...
    // (just in case you NEVER want to enter the loop)
    int count = 0;
    double sum = 0.0;
    while( enter() )
    {
        sum += addARYs();
        ++count;
    }
    if( count )
        cout << "\nAfter " << count
             << " loops, the GRAND Average = " << sum/count;
    else
        cout << "\nYou didn't request any numbers ...";
    cout << "\n\nPress 'Enter' to continue ..." << flush;
    cin.get();
}



And ...

// a little demo of a C++ 'forever' loop
// and a C++ do ... while(...) loop

// Note: both these above loops WILL ALWAYS be entered at least once ...
// whereas a 'for' loop and a 'while' loop MIGHT not be entered even once

#include <iostream>

using namespace std;

const char HEADER[] = "This program will calculate the area "
                      "of a circle, square, or triangle.";
const char MENU[] = "\n1) Circle, 2) Square, 3} Triangle.\n"
                    "Enter <1,2,3> or <c,s,t> : ";
const double PI = 3.14159;

// 1. an example of a C++ 'for' loop (used as a 'forever' loop)
// this function asks you to enter a value ...
// and loops until a valid value entered ... then,
// that valid value is returned.
double getValue( char prompt[], double low )
{
    double value;
    for( ;; ) // one common way in C++ to code a 'forever' loop ...
    {
        cout << prompt << flush;
        cin >> value;
        if( !cin.good() || value < low )
        {
            cin.clear(); // in case error flag set via non-numeric input
            cin.sync(); // 'flush' cin stream of char's there ...
            cout << "Invalid ... numbers only >= " << low << " please ...\n";
            continue; // right now ... from the for( ... ) condition at the top
        }
        // when reach here ... have a good number ... so ...
        cin.sync(); // 'flush' cin stream ...
        return value;
    }
}

// note that each of the following 3 shapes has its own function ...
void circle()
{
    double radius = getValue( "Enter radius: ", 0 );
    cout << "The area of the circle is " << PI*radius*radius << endl;
}

void square()
{
    double side = getValue( "Enter side: ", 0 );
    cout << "The area of the square is " << side*side << endl;
}

void triangle()
{
    double base = getValue( "Enter base: ", 0 );
    double height = getValue( "Enter height: ", 0 );
    cout << "The area of the triangle is " << base*height/2 << endl;
}

bool more() // defaults to yes ... more ...
{
    cout << "More (y/n) ? " << flush;
    int reply = cin.get();
    cin.sync();
    return reply != 'n' && reply != 'N';
}


int main()
{
    cout << HEADER << endl;
    
    // 2. an example of a loop that you always want to enter at least once
    do
    {
        cout << MENU;
        int choice = cin.get(); // note: cin.get() returns an 'int' value
        cin.sync();
        switch(choice)
        {
            case '1' : case 'c' : case 'C' : circle(); break;
            case '2' : case 's' : case 'S' : square(); break;
            case '3' : case 't' : case 'T' : triangle(); break;
            default : cout << "Not valid input ...\n";
        }
    }while( more() ); // more() asks for input and returns 'true' or 'false'
}


This post has been edited by David W: 23 January 2010 - 12:41 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1