• Create Account

## strange occurence mittle piecec++ code I wrote

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

10 replies to this topic

### #1patisake  Members

Posted 14 November 2012 - 06:09 AM

Hello everybody,

I have started with studying C++ and it goes very well since I never have learned a program language. I studied from the e-book juming into C++ which is a very good ebook for beginners.

Now I have wrote a piece of code and when I put in the numbers it is going good. But <hen I do a test and as a first number or in dutch type eerste number and then an a or b I get a very strange result..Can somebody explain why he is doing that?

the code is:

#include <iostream>
using namespace std;
int main ()
{
int eerste_liefdes_nummer;
int tweede_liefdes_nummer;

cout << "type eerste liefdes nummer: ";
cin>> eerste_liefdes_nummer;
cout << "type tweede liefdes nummer: ";
cin>>tweede_liefdes_nummer;
cout << eerste_liefdes_nummer << " * " << tweede_liefdes_nummer << " = " << eerste_liefdes_nummer * tweede_liefdes_nummer << endl;
cout << "jullie zijn heel erg verliefd";
}

Patrick

### #2Brother Bob  Moderators

Posted 14 November 2012 - 06:34 AM

Do you mean you literally type "a" or "b" instead of a number?

If that's the case, then your input fails because a number is expected. Let's say you type "a" letter instead of a number for the first number. The input is incorrect and the input fails, leaving the first variable unchanged and leaving the letter "a" in the input stream. When reaching the second input, the input stream still contains the letter "a" and you're trying to read the second number. This also fails, leaving the second variable unchanged, and again leaving the letter "a" in the input stream.

Now you have to variables with no particular value, and you proceed to print them.

### #3NightCreature83  Members

Posted 14 November 2012 - 06:38 AM

Als eerste welkom hier.

What you ran into happens because you don't initialise:
int eerste_liefdes_nummer;
int tweede_liefdes_nummer;

In C++ when you don't initialise a variable it will just contain random data, or to put this a bit more correctly just the data the that's in the location assigned to the variable.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

### #4patisake  Members

Posted 14 November 2012 - 07:16 AM

no, it does the following thing otherwise paste the code and test it....

type eerste liefdes nummer: a (I type a instead of a number and press enter)

the result is:type tweede liefdesnummer: 0 * 49 = 0 (that is what it puts on the screen after the enter of the first a

nightcreature..are you speaking dutch?spreek je nederlands?

### #5Waterlimon  Members

Posted 14 November 2012 - 07:57 AM

I dont know whats wrong but ill just list what i understood the problem to be:
1.You type "a" for the first number
2.You press enter

then it:
-completely skips waiting for the second number
-puts 49 in the second number, not the first number where it should be?
-tells you what they are multiplied (with the first number 0)

o3o

### #6patisake  Members

Posted 14 November 2012 - 08:03 AM

Okay, but where does he get this number 49?

### #7rip-off  Moderators

Posted 14 November 2012 - 08:40 AM

You can use [ code ] tags (without spaces) to get a pretty box to put your code in.

Okay, but where does he get this number 49?

If you don't initialise your variables, you have no guarantees about their content. It could easily be -1278468 as 49. The technical reason is that the variable represents a location in memory. C++ compilers generally do not fill memory with a particular value when acquiring it - any value they choose might not be a suitable. So instead C++ requires that each variable is suitably set before being read from. In your program you break this rule, because cin >> someVariable will only write to the variable if the read operation succeeds.

(note I'm going to simplify your code so I can read it)
If the user enters invalid input, step one is to detect and reject it. The standard C++ streams allow you to test whether input failed by using the "good" function.
#include <iostream>

using namespace std;

int main()
{
int x;
int y;
cout << "X: ";
cin >> x;
if(cin.good())
{
cout << "Y: ";
cin >> y;
if(cin.good())
{
cout << x << " * " << y << " = " << x * y << endl;
}
else
{
// Print error message
cout << "??? <img src='http://public.gamedev.net//public/style_emoticons/<#EMO_DIR#>/sad.png' class='bbc_emoticon' alt=':(' />" << endl;
}
}
else
{
// Print error message
cout << "??? <img src='http://public.gamedev.net//public/style_emoticons/<#EMO_DIR#>/sad.png' class='bbc_emoticon' alt=':(' />" << endl;
}
}

Step two is to handle it gracefully, by prompting the user to try again. For this we need to learn two new functions. clear() which "forgets" about the error, so we can try to read again. However, the user input is still sitting in the stream buffer, so if we try to read again we will get the same error. The ignore(n, c) function tells the stream to skip the next "n" characters unless you find the character "c". In this case, we want to ignore all the characters the user input up to the next newline. The simplest way to do that is to ask C++ to tell us the biggest number of characters supported (numeric_limits<streamsize>::max()).
#include <limits>
#include <string>
#include <iostream>

using namespace std;

while(true) {
cout << prompt;
int result;
cin >> result;
if(cin.good()) {
return result;
} else {
cout << "???" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
}

int main()
{
cout << x << " * " << y << " = " << x * y << endl;
}

There are still some downsides to this approach. For example, if the user types in "42 hello world" for the number X, the program responds like this:

X: 42 hello world
Y: ???
Y:

If the user types "42 13 loop the loop", the program does this:

X: 42 13 loop the loop
Y: 42 * 13 = 546

What we really want is to check if the user only entered a number, and proceed if so. Anything else is ambiguous.
There is another way - read the entire line as a string, and attempt to extract a number from this string. Then, check if there is nothing left in the string. The C++ standard library has some helpers for this. One is the function getline(), which reads an entire line into a string in one go. The next is stringstream, which is like cin but instead of reading from the standard input stream (usually the keyboard), it reads from a string you give it:
#include <string>
#include <sstream>
#include <iostream>

using namespace std;

while(true) {
cout << prompt;
string line;
getline(cin, line);
if(cin.good()) {
stringstream stream(line);
int result;
stream >> ws >> result >> ws;
if(!stream.fail() && stream.eof()) {
return result;
} else {
cout << "???" << endl;
}
} else {
cout << "???" << endl;
}
}
}

int main()
{
cout << x << " * " << y << " = " << x * y << endl;
}

Note that we are actually a little more flexible by allowing whitespace to precede or follow the number. The "ws" is a special function which eats whitespace from the stream. Also note that we can't just check "stream.good()". When the stream reaches the end, the stream is said to be at the "end of file" or eof(), and this means that stream is no longer good to read from. However, we don't really care if stream is good, as we won't be reading from it again. We care if it failed() to read. We also check that we have reached the "end of file", if not this means that the user typed more than a number surrounded by optional whitespace.

That is a reasonably robust program. There are a couple of cases it doesn't handle - such as cin reaching "end of file" (it can happen - it is possible to run your program with its input coming from a finite source such as a file or the output of another program), nor does it handle cout failing (it is also possible to run your program with its output connected to a file or another program, and this might fail, e.g. the disk becomes full). For programs which only need to handle interactive input handling these cases is nice-to-have but not strictly necessary.

### #8rip-off  Moderators

Posted 14 November 2012 - 08:43 AM

I forgot to mention this, but a common shortcut for reading a value from a stream and checking it succeeded is to place the read operation as the conditional expression:

For example:
if(cin >> someVariable) {
}

// or

while(getline(cin, line)) {
}


### #9Khatharr  Members

Posted 14 November 2012 - 08:51 AM

What does it return? Char count? [/lazymode]

Nvm, I looked it up. Returns .good(). Nice to know.

Edited by Khatharr, 14 November 2012 - 08:54 AM.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

### #10Álvaro  Members

Posted 14 November 2012 - 09:09 AM

Robust input from the user is surprisingly hard to do, as you can probably gather from rip-off's post. I rarely write programs where the user types anything in (my programs read command-line options and configuration files instead) but when I do, I always read the input line by line with std::getline(std::cin, line)' and then parse the line. In my experience it's the safest way to do things.

Since you are a beginner, it is likely that rip-off's code is too complicated for you at this stage. If that's the case, skip this whole robust-input thing and get on with learning the basics of the language (just be careful when you type ;) ). Once you are more comfortable with the language, come back and read his very useful code.

### #11NightCreature83  Members

Posted 14 November 2012 - 09:53 AM

no, it does the following thing otherwise paste the code and test it.... type eerste liefdes nummer: a (I type a instead of a number and press enter) the result is:type tweede liefdesnummer: 0 * 49 = 0 (that is what it puts on the screen after the enter of the first a nightcreature..are you speaking dutch?spreek je nederlands?

Ja, ik spreek Nederlands woon er alleen niet meer.

Robust input from the user is surprisingly hard to do, as you can probably gather from rip-off's post. I rarely write programs where the user types anything in (my programs read command-line options and configuration files instead) but when I do, I always read the input line by line with std::getline(std::cin, line)' and then parse the line. In my experience it's the safest way to do things. Since you are a beginner, it is likely that rip-off's code is too complicated for you at this stage. If that's the case, skip this whole robust-input thing and get on with learning the basics of the language (just be careful when you type ;) ). Once you are more comfortable with the language, come back and read his very useful code.

I found using JSON or XML parsers to be easier then using ini or text files. Also gives you the ability of skipping whole blocks if the code doesn't understand the content.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.