# Problem with loop in my beginner program

• February 16th, 2013, 05:53 PM
USCFan1990
Problem with loop in my beginner program
Hello, I am new here and I've searched around to try and find where I went wrong, but maybe I'm just not seeing it. So I decided to post it here in hopes that someone can point out my error. My program is a simple program. It asks you to add two random numbers together. It will then tell you if it is correct or incorrect. You then have the option to try a new problem or try to answer your previous problem again (I havn't established the correct code for trying the same problem again, because I wanted to test this program out first.) My problem is that after it is answered and calculated to be correct or incorrect, it automatically jumps out of loop and ends the program with "Okay." (Seen at the end of the program). Any advice? (Once again the "Incorrect" option has not been completed, it's simply a test to practice IF/ELSE and DO..WHILE loops).

Code:

```#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> using namespace std; int main() {     char input[1];     int x = rand() & 25;     int y = rand() & 25;     int a = x+y;     int answer;     cout<<"This program is a simple test. You must add 2 random numbers.\n\n";     do {         cout<<"The question is: " << x << "+" << y << "= ";         cin>>answer;         cout<<"\n\n";         if (answer == a){                 cout<<"Correct!\n\n";                 cout<<"Would you like to try a new problem? (y/n): ";                 gets(input);         }             else if (answer != a) {                 cout<<"Incorrect!\n\n";                 cout<<"Would you like to try again? (y/n): ";                 gets(input);             }     } while (strcmp (input, "y") == 0);     cout<<"Okay.";     cin.get(); }```

Thank you.
• February 16th, 2013, 06:21 PM
GCDEF
Re: Problem with loop in my beginner program
Input is defind as a one byte char array, which is not what you want. Just define it as a char, and check for equality using == 'y'. If you want to use string routines such as stricmp, you'll need to define it is a two byte array, the second byte being 0, which would make it a null terminated string.

Second problem, not sure exactly what you're going for with your random numbers, but it's not likely you want to use &. More than likely you meant the modulus operator which is %.
• February 16th, 2013, 06:31 PM
USCFan1990
Re: Problem with loop in my beginner program
Thank you for your reply. I defined input as input[1] instead of input so that the number of characters would only be 1. That way instead of defining all the yes's there can be, it's a simple y/n. Thank you for the suggestion with equality to 'y'. I used strcmp because I had been testing a simple calculator where you typed in 2 digits, then spelled the operation you wanted to use such as "Add, Subtract, Multiply, and Divide" so I got comfortable using strcmp to compare strings of letters. Thank you for the suggestions with the random numbers as well. Now I just have to come up with a solution so that when you try again if you get it wrong, it's the same problem (which the loop presents the same problem in this code anyway) and when you want a new problem it generates a new set of numbers. Thank you for the advice.
• February 16th, 2013, 09:10 PM
GCDEF
Re: Problem with loop in my beginner program
Hopefully you got the point that if you're going to use null terminated strings, you need to need enough space for the null terminator, which you didn't do. Your test is failing because whatever happens to be in memory right after you array, isn't null.
• February 17th, 2013, 01:52 PM
USCFan1990
Re: Problem with loop in my beginner program
Okay, so just so I'm clear (hopefully) a null terminated string is basically any contiguous string that has to end with a full bit pattern of all zero's (which is 'null' i assume?). The only other type of string would be std::string. That string doesn't need a null terminator because it is being kept in the std::string container, and can only be used by that container? If thats true, then it sounds like std::string would be more efficient then char string.
• February 17th, 2013, 02:10 PM
Paul McKenzie
Re: Problem with loop in my beginner program
Quote:

Originally Posted by USCFan1990
Okay, so just so I'm clear (hopefully) a null terminated string is basically any contiguous string that has to end with a full bit pattern of all zero's

Read what you just wrote above. You're defining "string" by using "string" in the definition.

A null terminated string is an array of char, where the array of char has as the last element in the array a value of 0.

A std::string is a class that handles string data as one complete entity, not individual chars in an array with a 0 at the end. There is no concept of "null termination" in a std::string, as the length of the string is stored in a member variable somewhere in the string class. In other words:
Code:

`std::string s = "abc123";`
That is one string variable called s, not an array of char with a 0 at the end.

Quote:

That string doesn't need a null terminator because it is being kept in the std::string container
Yes.
Quote:

and can only be used by that container?
I don't know what you mean. If you have routines that require null-terminated strings, then the std::string::c_str() function provides such a buffer. However, the buffer is not writeable, i.e. you can't change the contents of what is returned by c_str().

Regards,

Paul McKenzie
• February 17th, 2013, 02:16 PM
USCFan1990
Re: Problem with loop in my beginner program
Thank you Paul for clearing that up for me. One last question on this front. If I have a program that requires a set array of characters, and another set that can be altered by the user then I would use std::string for the set array of characters and char array for the characters inputted by the user?
• February 17th, 2013, 02:24 PM
Paul McKenzie
Re: Problem with loop in my beginner program
You can do that. If however you don't know the size of the changeable buffer, it is usually better to go with:
Code:

```#include <vector> typedef std::vector<char> CharArray; //... int main() {   CharArray s(10);  // an array of 10 chars, but much safer   int n = 30;   CharArray s2(n); // an array of n characters. You cannot do this with regular arrays   s2[0] = 'x';  // set the first character to x }```
Then when you want to pass the CharArray to another function that doesn't know anything about vectors, but only null-terminated strings, you pass the address of the first element of the vector.

Basically, you use the CharArray in the same way you were using the array of chars (it must be null-terminated also). The big difference with doing things using vectors as opposed to arrays is that array sizes must be known at compile-time, while vector sizes can be dynamic. Note the "n = 30" line, and how I used n to create a char array of n characters. Otherwise, you have to go the "new"/"delete" path, and I don't recommend it due to the extra pointer maintenance and probable memory leaks when introducing dynamically allocated memory.

The std::string class has recently made the internal buffer writeable, but to be safe for now, assume that you cannot write to the internal buffer. Therefore you have to use regular char arrays or std::vector<char> as writeable buffers (or use new[]/delete[], knowing all the caveats of going this route).

Regards,

Paul McKenzie
• February 17th, 2013, 02:42 PM
USCFan1990
Re: Problem with loop in my beginner program
Thank you so much. That explanation helps a lot, although I had to look up 'buffer' and 'vector' cause I'm not quite that far :p That seems like an incredibly useful way to handle array's compared to the beginner way, but I see why I needed to learn the basics first. My question is how would the 'n' size of the array be any less safe and cause memory leaks? A vector can dynamically change to accustom to it's contents can't it? Would the process of it changing multiple times over the course of the program cause it to 'miss' or 'lose' some information, where as the CharArray s(10) is ALWAYS 10? The way I'm thinking about it is if in the first part of the program I allow user input or a calculation leads to CharArray s2(n) to be, I don't know, 20, and the array of characters inputted was say, 10. It would then cause problems for that defined CharArray (s2 of course) if n was ever changed again to be say, 5? The data already stored would then be lost correct? So pre-determining the size of the CharArray will always be more useful then allowing the size to be dynamic? Or are there specific situations where that would be incorrect?
• February 17th, 2013, 03:35 PM
2kaud
Re: Problem with loop in my beginner program
Quote:

use std::string for the set array of characters and char array for the characters inputted by the user?
Using a char array (either standard c type or the vector type above) for input can be very dangerous. At the time of input the maximum number of characters that can be input is one less than the number of elements in the array/vector. If more characters are input than space has been allowed in the array/vector then the contents of memory following the array will be overwritten. c++ doesn't have bounds checking in this context. This is called buffer overflow and is a prime source of security problems with programs. It is much better to use std::string for input as the size of the string is dynamically extended to fit the number of characters entered.

Code:

```//BAD CODE char myinp[20]; gets (myinp);```
In this example, if less than 20 characters are entered (max 19 plus 1 for the terminating NULL) then its OK. However, if 20 or more characters are entered then whatever happens to be in memory following myinp (possibly part of the program or more data) is overwritten with disasterous results.

Code:

```#include <iostream> #include <string> using namespace std; string myinp; cin >> myinp; cout << myinp;```
In this case, the size of myinp dynamically expands to accomodate all the characters input and buffer overflow does not occur.

c-style strings are just an array of char with a terminating 0 as the final character. std::string is a class in which the data stored is manipulated via methods or overloaded operators. Unless you have a good reason to use c-style strings, the string class is usually better used.

Code:

```char s1[] = "abcdef"; char s1[] = "zxcvb"; if (!strcmp(s1, s2)) ...```
tests for equality of c-style strings whilst the same using string classs is

Code:

```string s1 = "abcdef"; string s2 = "zxcvb"; if (s1 == s2) ...```
which is much easier to write and more intutive to read.

A vector is a class, just like string is a class, and has its own methods and operator overloading for manipulating the data it holds. When data is added to a vector class using the vector methods (insert or push_back) then the 'size' of the vector is extended and all existing stored data is preserved. However, a vector does not have bounds checking. So if a vector has 4 elements and the element 5 is accessed then this is a runtime error and the behaviour is undefined (probably crashes the program).

Using Paul's CharArray example,

Code:

```int n = 10; CharArray myinp(n);```
This creates a char vector of 10 elements so can hold 9 chars (plus terminating NULL). So
Code:

`strcpy(&myinp[0], "hello");`
is fine as hello is length 6. But

Code:

`strcpy(&myinp[0], "hello from 2kaud");`
is not as it has more than 9 chars and so overruns the memory allocated for the vector. This is why it's better to use the string class where you can so you don't get memory overlow.

Code:

```string s1; s1 = "hello"; s1 = "hello from 2kaud";```
both the assignments are OK as s1 is automatically extended to match the size required.

Hope this, somewhat long! explanation helps. I know its a tricky area for someone learning c++ but once its understood it really is quite easy to use.