473,386 Members | 1,598 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

A small question

Hello everyone,

I'm just getting started playing around with C++, so please don't laugh
too loudly at my crude source code, okay? (o^^o)

I'm combining together several introductory exercises into one small
program. My compiler and IDE is Visual C++ Express Edition, and the
book I'm using is Teach Yourself C++ in 24 hours by Jesse Liberty and
David Horvath. While playing around with the code a little bit I found
something I couldn't understand.

The program only uses "int" variables (except for one small string). I
have a function called "LoopExp" that takes input from the user and
stores it in FirstNumber. LoopExp then calls another function,
"CompareNumbers" to do a quick division exercise. Naturally, I need
two numbers, so CompareNumbers gets a variable called SecondNumber from
the user.

If the user inputs a number with a decimal point for FirstNumber (i.e.,
4.5), then the CompareNumbers function pulls garbage off the stack and
will not run correctly. I tried using a forced typecast on
FirstNumber, int(FirstNumber), but naturally the compiler returned an
error.

Is there an easy way to prevent CompareNumber from pulling garbage off
the stack or do I just have to wait until I study exception handling?

The source code is below. Many thanks to anyone who takes the time to
offer a reply!

Brian K. Miller

--------------------------------------------------------------------------------------------------------------------------

#include <iostream>

using namespace std;

void LoopExp(); // Declare the LoopExp()
function
void CompareNumbers(int FN); // Declare the CompareNumbers()
function
int main()
{
char Name[64];

cout << "\nIs this thing on?" << endl;
cout << "Oh, sorry! I guess it is." << endl;
cout << "As long as I have your attention, what's your name?\t";
cin >> Name;
cout << "Hello, " << Name << ". Pleased to meet you!" << endl <<
endl;

// From this point we call some functions containing other
examples

LoopExp(); // Contains an example of a simple do-while loop

return 0;
}

void LoopExp()
{
/* This function asks for a number from the user, checks to make
sure their input is within bounds (but does NOT check for
character
input!) then outputs "I love games!" to the screen for the same
number of times as the user's input.
*/

int FirstNumber = 0;

cout << "So, let's play a game! Give me a number from 1 to 10: ";
cin >> FirstNumber;

/*
NOTE: If the user inputs a number with a decimal point (i.e.,
4.5)
for FirstNumber then the CompareNumbers() function will not
work
properly and the program will display garbage!
*/

CompareNumbers(FirstNumber);

if (FirstNumber < 1 || FirstNumber > 10) // check for an input
error
{
cout << "You're no fun!" << endl;
}
else
{
do
{
cout << "I love games!" << endl; // output the message
FirstNumber--; // decrement
the number
} while (FirstNumber != 0);
} // end of if-else

cout << endl; // move cursor down one line

} // end of LoopExp()
void CompareNumbers(int FirstNumber)
{
/* This function asks for a second number larger than the first,
but less than 100. It then uses the modulus operator to see
if they are evenly divisible. If they are, it checks to see
if the user entered 10 twice (the only possible duplication).
If the numbers are evenly divisble it outputs the correct
answer.
If they are not evenly divisble, it apologizes and outputs
the integer component of the answer.

NOTE: If the user inputs a number with a decimal point for
SecondNumber, then the program will strip off the remainder
and just use the integer portion.
*/

int SecondNumber = 0;
int Temp = 0;
int FN = 0;

FN = FirstNumber;

cout << "Now give me a number between 10 and 100: ";
cin >> SecondNumber;

if (SecondNumber < 10 || SecondNumber > 100) // check for an
input error
{
cout << "Hey! " << SecondNumber << " is not what I asked for!"
<< endl;
}
else
{
Temp = SecondNumber / FN;

if ((SecondNumber % FN) == 0) // check if they are evenly
divisble
{
if (SecondNumber == FN)
{
cout << "You really like the number 10, don't you?" <<
endl;
}
else
{
cout << "\nOh, cool! They are evenly divisible!" <<
endl;
cout << "The second number divided by the first is: " <<
Temp << endl << endl;
} // end of "Oh, cool!"
} // end of "check for evenly divisible"
else
{
cout << "\nI tried to divide " << SecondNumber << " by " <<
FN;
cout << ", but I can't do fractions." << endl;
cout << "Still, " << Temp << " is pretty close, right?" <<
endl << endl;
} // end of "I can't do fractions"
} // end of else section following initial error check for
SecondNumber
} // end of CompareNumber()

Feb 28 '06 #1
2 2040
BKMiller wrote:
If the user inputs a number with a decimal point for FirstNumber (i.e.,
4.5), then the CompareNumbers function pulls garbage off the stack and
will not run correctly.
Well, more precisely, 'FirstNumber' will become "4" and the next
character to be read will be "." which is not a valid start for
an 'int'. Thus, the next attempt to read an 'int' from the stream
will fail, set corresponding state flags in the stream, and leave
the corresponding variable uninitialized.

You should always check the result from input, especially if it is
manual input. This could look like this:

if (std::cin >> var)
/* processing of successful read goes here */
else
/* processing of wrong input goes here */

Depending on what you are doing, recovery from an input error may
take different forms. In your situation you probably want to try
to recover from the error situation, e.g. by ignoring everything
on the current line:

// execute the loop until we could either successfully read
// a value or end of file is reached:
while (!(std::cin >> var) && !std::cin.eof())
{
std::cin.clear(); // clear the error flags
// ignore an arbitrary amount of character until end of line
std::cin.ignore(std::numeric_limits<std::streamsiz e>::max(), '\n');
}
if (std::cin.eof())
throw std::runtime_error("EOF while reading a value");

In many situations no recovery is attempted and the processing of
the file is immediately terminated with an appropriate error.
Is there an easy way to prevent CompareNumber from pulling garbage off
the stack
Actually, this is not at all happening.
char Name[64];
cin >> Name;


This is a receipt for buffer overflows! There are two options to
make sure that no buffer overflow occurs:

1. The preferred option is to use an 'std::string' instead of a
fixed size array:

#include <string>
// ...
std::string Name;
std::cin >> Name;

This is less error-prone and accommodates for the possible use
of rather long names.

2. You can setup the maximum number of characters to be read by
setting the width:

#include <iomanip>
// ...
char Name[64];
std::cin >> std::setw(sizeof(Name)) >> Name;

This will limit the number to be read to be 'sizeof(Name) - 1'.
The extra character is need to store a terminating null character.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence
Feb 28 '06 #2
On 27 Feb 2006 22:56:32 -0800, "BKMiller" <su*****@hotmail.com> wrote:
<...>

Is there an easy way to prevent CompareNumber from pulling garbage off
the stack or do I just have to wait until I study exception handling?
Yes, test if input conversion has failed
<...>void LoopExp()
{
/* This function asks for a number from the user, checks to make
sure their input is within bounds (but does NOT check for
character
input!) then outputs "I love games!" to the screen for the same
number of times as the user's input.
*/

int FirstNumber = 0;

cout << "So, let's play a game! Give me a number from 1 to 10: ";
cin >> FirstNumber;

/*
NOTE: If the user inputs a number with a decimal point (i.e.,
4.5)
for FirstNumber then the CompareNumbers() function will not
work
properly and the program will display garbage!
*/
if (cin.fail()) {/*Do whatever you think is fit */}

CompareNumbers(FirstNumber);
<...>void CompareNumbers(int FirstNumber)
{
/* This function asks for a second number larger than the first,
but less than 100. It then uses the modulus operator to see
if they are evenly divisible. If they are, it checks to see
if the user entered 10 twice (the only possible duplication).
If the numbers are evenly divisble it outputs the correct
answer.
If they are not evenly divisble, it apologizes and outputs
the integer component of the answer.

NOTE: If the user inputs a number with a decimal point for
SecondNumber, then the program will strip off the remainder
and just use the integer portion.
*/

int SecondNumber = 0;
int Temp = 0;
int FN = 0;

FN = FirstNumber;

cout << "Now give me a number between 10 and 100: ";
cin >> SecondNumber;
if (cin.fail()) {/*Do whatever you think is fit */}

if (SecondNumber < 10 || SecondNumber > 100) // check for an
input error
{
cout << "Hey! " << SecondNumber << " is not what I asked for!"
<< endl;
}
else
{
Temp = SecondNumber / FN;

if ((SecondNumber % FN) == 0) // check if they are evenly
divisble
{
if (SecondNumber == FN)
{
cout << "You really like the number 10, don't you?" <<
endl;
}
else
{
cout << "\nOh, cool! They are evenly divisible!" <<
endl;
cout << "The second number divided by the first is: " <<
Temp << endl << endl;
} // end of "Oh, cool!"
} // end of "check for evenly divisible"
else
{
cout << "\nI tried to divide " << SecondNumber << " by " <<
FN;
cout << ", but I can't do fractions." << endl;
cout << "Still, " << Temp << " is pretty close, right?" <<
endl << endl;
} // end of "I can't do fractions"
} // end of else section following initial error check for
SecondNumber
} // end of CompareNumber()

Regards,

Zara
Feb 28 '06 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Randall Parker | last post by:
Using IE 6.x (whatever is the latest) on Windows 2000. For these two CSS definitions if I remove the 2 lines that have the "mso-" font family definitions (mso-fareast-font-family, and...
7
by: Sharon | last post by:
Hiya I have a small question, I saw this piece of code somewhere (it's for creating a customized context menu) and I was wondering: Why is it that the STYLE and SCRIPT-tags are broken up into...
3
by: Tim | last post by:
Hi Group, Apologies if this is a bit OT (if so, please advise where it should be posted). I was wondering if anyone had any ideas as to what applications could work in a system where the...
5
by: Geoff Cox | last post by:
Hello Would be grateful if someone can make a few things clear for me! I have developed a small app using Java and would like to do the same using C++ but without the need for a runtime...
1
by: Gena | last post by:
Hi , I'm a newbe to programming and have a small question: I made a small program with a class. in the class's header file I have : double *ptr_output; Void main() { double result;
4
by: =?Utf-8?B?VzFsZDBuZTc0?= | last post by:
When one architects a new project one of the first steps in the decision is to decide on the layers. (In my opinion anyway) One architecture that I have used before is to go solid OO and create...
1
by: =?Utf-8?B?cmJiZW5zb24=?= | last post by:
To begin,, the network infactructure- Servers - Server00 - Windows Server 2003/Installed Server01 - Windows Server 2003/plan to install Server10 - Linux RedHat Workstation/Installed ...
169
by: JohnQ | last post by:
(The "C++ Grammer" thread in comp.lang.c++.moderated prompted this post). It would be more than a little bit nice if C++ was much "cleaner" (less complex) so that it wasn't a major world wide...
4
by: ATS16805 | last post by:
Hi. I wonder if it's possible to "force" a browser to "switch to SSR mode" for any given document. Specifically, I'm looking for a solution, not to a User Agent issue (i think), but a coding idea;...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.