Vector: range error at memory - c++

I have been programming a bit with C++ in CodeBloks before and since some time i started to program in MS Studio. At the moment im programming a little game from the book: Programming: Principles and Practice using C++. Exercise 12 of chapter 5.
I have been looking around on the internet to fix the range memory error which keeps occuring whatever I try (see printscreen link).
The description about the program is in the code itself.
I also did make the vectors a hard coded (if I say that right) size to make the program stop complaining about their memory range errors.
Note: Yes this is a school exercise/practice as well. But I rather ask what I did wrong then copy paste the code from the internet..
Please look over my code and see or I made some mistake with me vectors, cause that is where my errors are probably comming from.
Update: placed as answer in this topic.
Link to update
Error:
Unhandled exception at 0x7529CBC2 in Tweede project.exe: Microsoft C++ exception: Range_error at memory location 0x006FF510.
Program:
#include "std_lib_facilities.h"
int main(){
bool while_bit = false;
vector<int>bulls_cows(4);
vector<int>inputs_arr(4);
//Generate 4 random numbers.
for (int a = 0; a < 4; ++a){
bulls_cows[a] = a + 1;//randint(a) % 9 + 0; //random number between 0 and 9.
}
//bulls_cows[1] = randint(10);
cout << "For this game, called Bulls and Cows, you have to guess the four right numbers between 0 and 9.\n";
cout << "When one or more digets are right and in the right position the program will say the number of Bulls.\n";
cout << "When one or more digets are right but not in the right position the program will say the number of Cows.\n";
cout << "Please enter 4 number by filling in ONE positive diget and press enter. Do this four times and wait for the result.\n";
for (int z = 0; z < 4; ++z) {
cout << bulls_cows[z] << "\n";
}
while (while_bit == false) {
int input = 0; //Reset of input, cows and bulls every round.
int cows = 0;
int bulls = 0;
cin >> input;
//Test for legit input. If legit then it writes it to the array called "input_arr"
if (input < 0 || input > 9) {
cout << "Number must be between 0 and 9.\n";
}
else {
inputs_arr.push_back(input);
}
//Check or 4 numbers have been given.
if (sizeof(inputs_arr) < 4) {
//Check for equal numbers on same spot.
for (int b = 0; b < 4; ++b) {
if (inputs_arr[b] == bulls_cows[b]) {
bulls + 1;
}
}
//Check for a number in all spots.
for (int c = 0; c < 4; ++c) {
if (inputs_arr[c] == bulls_cows[0] || bulls_cows[1] || bulls_cows[2] || bulls_cows[3]) {
cows +1;
}
}
}
if (bulls < 4) {
cout << "You did not guess the right combination.\n";
cout << "Number of bulls: " << bulls << "\n";
cout << "Number of cows: " << cows << "\n";
inputs_arr[0, 0, 0, 0]; //Empty array.
}
if (bulls == 4) {
cout << "You guessed the right combination!\n";
while_bit = true;
}
}
keep_window_open(); //To keep terminal open since MS Studio doesn't itself.
return 0;
}

Using the sizeof operator with your inputs_array vector will give you the size in bytes of that object in memory. Perhaps you've used this with arrays before.
Instead, I think you want the number of items you've pushed into the vector. std::vector has a function called size which gives the number of items pushed to it.

In Visual Studio you should really, really set up the warning level to level 4. Then the compiler will tell you about several of the odd things you try to do.
For example:
warning C4552: '+': operator has no effect; expected operator with side-effect 1>
bulls + 1;
You compute a result, but never store it anywhere. Same thing for the cows.
error C4548: expression before comma has no effect; expected expression with side-effect
inputs_arr[0, 0, 0, 0]; //Empty array.
This is not the way to empty an array. To remove all elements, you do inputs_arr.clear();.
warning C4127: conditional expression is constant
if (sizeof(inputs_arr) < 4) {
Like we have already seen, sizeof is the size of the vector object (always the same), not the number of elements it holds.
Then there are some logic errors.
vector<int>inputs_arr(4);
This creates a vector originally holding 4 ints.
But later when you do
inputs_arr.push_back(input);
it adds more elements to the vector, so now it might hold up to 8 ints. You have to decide if you want to create it with the full size up front, or add elements as you go along. But not both.
Another problem is with the condition
if (inputs_arr[c] == bulls_cows[0] || bulls_cows[1] || bulls_cows[2] || bulls_cows[3]) {
Even though there are languages where you can write conditions similar to this, in C++ you cannot. To compare a variable x to several other values, you have to spell it out:
if (x == y || x == z || x == w)

Update: (wasn't sure or I had to add it to the question or as answer. If wrong, please let me know. Im new to Stack overflow ;) )
It seems some statement/loop brackets where not placed right. I edit that and a bit:
Sadly it seems that my intergers cows and bulls do not reset at line 61 and 62.. Anyone a idea what I might have done wrong there.
LOG:
cin did not not loop. Also edited else-statement 'inputs_arr.pushback(input)' and added all for-loops and statements below it. Fixed a part of the cin problem.
Replaced bulls, cows and input integers to top of program, and the reset at the end of the false/if-statement.
Put all loops and statements below the if-statement '(int b = 0; b < 4; ++b)' into it.
Edited the for-loop to >4 which couts "Size of array" to see what values it has. Gets deleted later on cause it is for test only.
#include "std_lib_facilities.h"
int main()
{
bool while_bit = false;
int input = 0;
int cows = 0;
int bulls = 0;
vector<int> bulls_cows(4); //size needed to prevent memory size error at line 11.
vector<int> inputs_arr;
//Generate 4 random numbers. Need to add seed later.
for (int a = 0; a < 4; ++a){
bulls_cows[a] = randint(a) % 9 + 0; //random number between 0 and 9.
}
cout << "For this game, called Bulls and Cows, you have to guess the four right numbers between 0 and 9.\n";
cout << "When one or more digets are right and in the right position the program will say the number of Bulls.\n";
cout << "When one or more digets are right but not in the right position the program will say the number of Cows.\n";
cout << "Please enter 4 numbers by filling in ONE positive diget and press enter. Do this four times and wait for the result.\n";
for (int z = 0; z < 4; ++z) { //Gives the generated numbers for testing.
cout << bulls_cows[z] << "\n";
}
while (while_bit == false) {
cin >> input;
//Test for legit input. If legit then it writes it to the array called "input_arr"
if (input < 0 || input > 9) {
cout << "Number must be between 0 and 9.\n";
}
else {
inputs_arr.push_back(input);
//Check or 4 numbers have been given.
if (inputs_arr.size() > 3) {
//Check for equal numbers on same spot.
for (int b = 0; b < 4; ++b) {
if (inputs_arr[b] == bulls_cows[b]) {
++bulls;
}
}
//Check for a number in all spots.
for (int c = 0; c < 4; ++c) {
if (inputs_arr[c] == bulls_cows[0] || inputs_arr[c] == bulls_cows[1] || inputs_arr[c] == bulls_cows[2] || inputs_arr[c] == bulls_cows[3]) {
++cows;
}
}
/*for (int x = 0; x < 4; ++x) { //Couts again the fresh entered numbers for a better overview.
cout << "Size of array: " << inputs_arr[x] << "\n";
}*/
if (bulls < 4) {
cout << "You did not guess the right combination.\n";
cout << "Number of bulls: " << bulls << "\n";
cout << "Number of cows: " << cows << "\n";
int cows = 0; //Reset of cows and bulls each round.
int bulls = 0;
inputs_arr.clear(); //Empty the array.
cout << "Please enter 4 numbers:\n";
}
if (bulls == 4) {
cout << "You guessed the right combination!\n";
while_bit = true;
}
}
}
}
keep_window_open(); //To keep terminal open since MS Studio doesn't itself.
return 0;
}

Related

Having trouble setting a range a numbers that a user can input

I am writing a program and have everything working fine except the function below. I am curious as to what would work best to make it so that the users inputs for the first loop can only be from 1 - 69, and the second loop from 1 - 26.
I was going to do a do/while loop but got an error as mentioned below.
//***********************************************
//Case 4 lets you input your own lottery numbers*
//***********************************************
void case4()
{
cout << numberprint << endl;
tickettop();
int array_pick[4];
int pballp;
for (int i = 0; i < 5; i++)
{
cout << evalue << i + 1 << space1;
do
{
cin >> array_pick[i];
} while (array_pick > 0 && array_pick <= 69); //Here is where I get an error for array_pick <= 69 (operand types are incompatible ( int * and int))
}
for (int i = 0; i < 1; i++)
{
cout << eball;
cin >> pballp;
}
cout << endl << endl;
ofs << endl;
ticketbottom();
ofs << bar << box << bar << endl;
}
int lottonumber;
ask: //goto label
cin >> lottonumber; //prompt value in console
//if lower than 1 or higher than 69, goto label
if (lottonumber < 1 || lottonumber > 69)goto ask;
People dislike the goto label, but in this case its not a problem. While loops and for loops are there to make the code more understandable and organizable. The goto label wont make your program slow or 'bad', it will just make it harder to organize. Or in this case, easier.
Your code has a number of issues. There are 2 issues with this line:
} while (array_pick > 0 && array_pick <= 69);
Firstly, you are comparing an array to an integer, that's where the compiler error comes from. Secondly, the condition should be the opposite to what it is now: you want the loop to continue until the user enters a correct value, therefore you need the condition to be true if the entered value is out of range, not when it's actually correct.
What you probably mean to do is this:
} while (array_pick[i] < 0 || array_pick[i] > 69);
To check the second input you can use the same do...while construct, just change the condition:
cout << eball;
do
{
cin >> pballp;
} while (pballp < 0 || pballp > 26);
But there are other problems with your code, even though the rest of it is syntactically correct, as far as I can tell.
The first loop will go out of bounds of your array_pick array.
for (int i = 0; i < 5; i++)
i will take values 0, 1, 2, 3 and 4, but the array you're modifying in this loop is defined as int array_pick[4], so there will only be elements with indexes 0, 1, 2 and 3.
The second for is pointless, as the loop will only ever do a single iteration.

C++ For-Loop Gets stuck when entering new variables [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I'm new to C++ and trying to create a lottery game for a college project.
I have a for loop to check that there are no duplicate numbers in the array entered. This works absolutely fine when you take out the section of code to produce the random numbers.
As soon as I add the random number section back in, the for loop just gets stuck. It will continuously tell me that i have already entered the number when its trying to store the first number.
I have attached all of my code, apologies if you don't need it all.
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
//int loto[6];
int main()
{
int numbers[6];
//void rand_num(int loto[6], int count);
int loto[6]; //used to store the loto numbers
//int james = 0;
//int l,j; //used in checking any duplicated
srand(time(0));
for(int count=0; count<6; count++)
{
loto[count] = (rand()%49)+1;
cout << loto[count] << endl;
}
//declares the variable i to increase each time a number is entered.
//this will only go as high as 6
for(int i=0;i<6;i++)
{
cout<<" " << i<<" : Please enter your lottery numbers: "<<endl;
cin>>numbers[i];
if ((numbers[i] >= 50) | (numbers[i] == 0))
do
{
{
//checks to see if the first number entered is above 50 or = to 0 and rejects it
cout << "The Number must be between 1-49, please select again. " << endl;
cin >> numbers[i];
}
}
while ((numbers[i] >= 50) | (numbers[i] == 0));
//----------------------------------------------------------------------------
//this section of code is a loop within a loop to check the number entered against all numbers already stored.
//makes l the same as i effectively
for(int l=0;l<6;l++)
{
//makes j one more than l
for(int j=l+1;j<7;j++)
{
if( numbers[l] == numbers[j] )
do
{
{
cout << "Number has already been chosen, please re-enter number " << endl;
cout << endl;
cin >>numbers[i];
//checks the number that is re-entered is not <50 or = 0
//if so it rejects it and asks for another as above.
if ((numbers[i] >= 50) | (numbers[i] == 0))
do
{
{
cout << "The Number must be between 1-49, please select again. " << endl;
cin >> numbers[i];
}
}
while ((numbers[i] >= 50) | (numbers[i] == 0));
}
}
while (numbers[l] == numbers[j]);
}
}
}
//----------------------------------------------------------------------------
//this displays the numbers that have been chosen.
cout << "Your Numbers are: " << endl;
for (int i = 0; i<6; i++)
{
cout << " " << numbers[i];
}
return 0;
}
I'm not sure this is the real problem but it is a bug. Try to correct it and see if it helps.
for(int l=0;l<6;l++)
{
//makes j one more than l
for(int j=l+1;j<7;j++)
{
if( numbers[l] == numbers[j] )
The inner-loop will reach j==6 so you will access outside the array. The outer-loop shall have 5 as the limit and the inner-loop shall have 6 as the limit.
EDIT:
After looking a bit more at your code I can see that you are using numbers[] without initializing it. The two nested for-loops will compare all elements in numbers. But if the user have only entered 2 numbers, the rest is unitialized and can give unintended results.
Further - you don't need to check all elements againt all elements every time. Just check the newly entered number (index by i) with all previous numbers.
Finally you will probably need something like:
if (!(cin >> numbers[i])) {
cout << "Please enter numbers only." << endl;
cin.clear();
cin.ignore(10000,'\n');
}
to handle input not being integer, e.g. "text"
And to minor things:
You should also check for negative numbers.
You are using | instead of ||. It will work fine but || seems more correct as it is the logical OR (while | is a binary OR).

Addition and subtraction of arrays

I have been working on this all day but just cant get the output right.
What I want to do is input two numbers, which would be pushed into two arrays so we can subtract or add them and display the result. Seems simple, but there are few catches
Input must be pushed into the array, from the user, one by one.
In case I don't enter a value, code should assume it to be '0' or 'null'. '0' if its in the beginning and 'null' if its in the end. for example if 1st number is 234 and second number is 23 then code should make it into '023' and if I enter first number as 2, 2nd number as 3 but don't enter anything in the end then code should assume it to be null.
Problems
I cant take 'carry' to the next set, in case the sum is greater than 10. Which means the value I m getting is just addition of two numbers doesn't matter if its greater than 10 or not. for example addition of 234 and 890 is giving me [10, 12, 4]
Here is the code.....
#include<iostream>
using namespace std;
main() {
int first[10], second[10], result[10], c, n;
cout << "Enter the number of elements in the array ";
cin >> n;
if (n > 10 || n < 0) {
std::cout << "invalid number, you are a bad reader" << endl;
system("PAUSE");
return 0;
}
cout << "Enter elements of first array " << endl;
for (c = 0; c < n; c++) {
cin >> first[c];
if (first[c] > 9 || first[c] < 0) {
std::cout << "invalid number, you are a bad reader" << endl;
system("PAUSE");
return 0;
}
}
cout << "Enter elements of second array " << endl;
for (c = 0; c < n; c++)
cin >> second[c];
cout << "Sum of elements of two arrays " << endl;
for (c = 0; c < n; c++)
cout << first[c] + second[c] << endl;
if ((first[c] + second[c]) > 9) {
cout << "overflow" << endl;
}
//result[c] = first[c] + second [c];
//cout << result[c] <<endl;
system("PAUSE");
return 0;
}
I would really appreciate some suggestions.
In case your intention is to have the result of e.g.
234 + 890 = 1124
then your summation loop should be in reverse order.
(Since you are reading number of elements of the array from the prompt, you may use this information to input first/second numbers into each array in the order preferred for the following summation loop.)
For the carry problem, you need to setup a variable and use it in the loop like this, for example.
int sum[10] = {0};
int c;
int carry = 0;
for (c = 0; c < n; c++)
{
sum[c] = first[c] + second[c] + carry;
carry = sum[c] / 10;
}
if (c < n)
sum[c] = carry;
else
cout << "overflow";
Use std::vector and learn how to use reverse iterators. So if someone enters 234 you push_back(2), push_back(3), push_back(4) and have [0]=2,[1]=3,[2]=4. Then if the next number is 23 you have [0]=2,[1]=3. Now walk both vector with reverse iterators so the first call to rbegin() will give a pointer to [2]=4 and the other vector will give [1]=3. Now add and carry using push_back into a third vector to store the result. Output the result using reverse iterators to print the result.
This looks like homework, so no sample code.

C++ extraneous for loop needed for program to run successfully

Before we start, yes this is homework, no i'm not trying to get someone else to do my homework. I was given a problem to have someone enter a binary number of up to 7 digits and simply change that number from binary to decimal. Though i'm most certainly not using the most efficient/best method, i'm sure I can make it work. Lets look at the code:
#include <iostream>
#include <math.h>
using namespace std;
int main() {
char numbers[8];
int number = 0, error = 0;
cout << "Please input a binary number (up to 7 digits)\nBinary: ";
cin.get(numbers, 8);
cin.ignore(80, '\n');
for (int z = 7; z >= 0; z--){}
cout << "\n";
for (int i = 0, x = 7; x >= 0; x--, i++){
if (numbers[x] <= 0){ // if that is an empty space in the array.
i--;
}
else if (numbers[x] == '1'){
number += pow(2, i);
}
else if (numbers[x] != '0'){ // if something other than a 0, 1, or empty space is in the array.
error = 1;
x = -1;
}
}
if (error){ // if a char other than 0 or 1 was input this should print.
cout << "That isn't a binary number.\n";
}
else{
cout << numbers << " is " << number << " in decimal.\n";
}
return 0;
}
If I run this code it works perfectly. However in a quick look through the code there is this "for (int z = 7; z >= 0; z--){}" which appears to do absolutely nothing. However if I delete or comment it out my program decides that any input is not a binary number. If someone could tell me why this loop is needed and/or how to remove it, it would be much appreciated. Thanks :)
In your loop here:
for (int i = 0, x = 7; x >= 0; x--, i++){
if (numbers[x] <= 0){ // reads numbers[7] the first time around, but
// what if numbers[7] hasn't been set?
i--;
}
you are potentially reading an uninitialized value if the input was less than seven characters long. This is because the numbers array is uninitialized, and cin.get only puts a null terminator after the last character in the string, not for the entire rest of the array. One simple way to fix it is to initialize your array:
char numbers[8] = {};
As to why the extraneous loop fixes it -- reading an uninitialized value is undefined behavior, which means there are no guarantees about what the program will do.

Cannot return to userinput line and cannot print out the board

I have been working for an hour on this function. I try to get the return to go back to the user question "Enter the size board" when it goes to 2nd for statement, but it ends the program instead. Other issue is the program stops on the line, "int makeBoard[row][column];" when I ran the debug so therefore it causes not to print out the board. Whats up with that??
void showBoard()
{
int i;
int boardSize;
if(i > 3 || i < 13)
{
cout << "Enter the size board you want, between 4 and 12: ";
cin >> i;
cout << "The number you entered is: " << i;
if(i < 4 || i > 12)
{
cout << "\nYou entered the invalid number, read the direction again.\n";
return;
}
cout << " ";
cout << "\nGame ends when you reach 1024.\n";
}
int row = boardSize;
int column = boardSize;
int x, y;
int makeBoard[row][column];
for(x = 0; x < row; x++)
{
for(y = 0; y < column; y++)
{
makeBoard[x][y] = '.';
printf(" %c", makeBoard[x][y]);
}
printf("\n\n");
}
}
The following, critical, variables are not initialize: i and boardSize.
If you do manage to get past the first if statement, nothing initializes the boardSize variable.
Edit 1:
The variable i is only used to annoy the program. It is not assigned to anything.
Edit 2:
Your board is declared to be signed integers, but you assign it characters. Shouldn't it be declared a board of characters?
Edit 3: -- Printing the board
If you add an additional column to the board, you could use the last column to hold '\n'. That way you would only need one print statement for each row.
Edit 4: putchar vs. printf
If you know you are printing a character, use putchar rather than printf. The printf function has extra overhead because it has to parse the formatting string. The putchar function takes the character and writes it to the output; no formatting required, more efficient.
If you propagate this idea, you could append another row. The first column of this row would contain '\0'. This change, combined with the above, allows you to print the board with one print statement and no for loop. Wow!
The input you have asked to the user ,was for variable "i". Whereas,row and coloumn are given value of uninitialized variable "Boardsize".
You need to put "Boardsize" at the place of the "i" or vice versa.
and also in the conditional statement for handling error, you have used return ,whereas you are not returning any value....so for that case I recommend you to use "cin>>boardsize; " at the place of "return" to handle error more precisely.
Makeboard array needs to be of char type to print '.' or as int, the block will print "46",which is ASCII value of '.'
int main() {
int boardSize;
if(boardSize > 3 || boardSize < 13) {
cout << "Enter the size board you want, between 4 and 12: ";
cin >> boardSize; // take input for boardsize ,not i
cout << "The number you entered is: " << boardSize;
if(boardSize < 4 || boardSize > 12)
{
cout << "\nYou entered the invalid number, read the direction again.\n";
cin>>boardSize; // change return by this statement
}
cout << " ";
cout << "\nGame ends when you reach 1024.\n";
}
int row = boardSize; //earlier the problem was in this line
int column = boardSize; //also here
int x, y;
char makeBoard[row][column]; // also you need this array of char data type to print '.'
for(x = 0; x < row; x++) {
for(y = 0; y < column; y++) {
makeBoard[x][y] = '.';
cout<<makeBoard[x][y];
}
printf("\n\n");
}
getch();
return 0;
}
It seems to me as if you don't understand exactly what the 'return' keyword is designed to do. Similarly, your code has many mistakes in it. I'd suggest reading a tutorial or C++ book.
Return is designed to exit the current function (i.e. if you have return at the beginning of the function, it would literally do nothing).
Also, it's a mistake to not initialize your variables upon declaring them. Instead of int i; consider int i=-1;. Otherwise, the result will be undefined. i could be equal to 10 or 100000 or -20002393.
int i=-1;
while(true) // Do this forever
{
cout << "Enter the size board you want, between 4 and 12: ";
cin >> i;
cout << "The number you entered is: " << i;
if(i < 4 || i > 12)
{
cout << "\nYou entered the invalid number, read the direction again.\n";
}
else break; // You can leave the loop!
}
cout << " ";
cout << "\nGame ends when you reach 1024.\n";
This isn't the best way to do it, but I hope it gives you an idea. Also, please go through some tutorials before you post rather basic questions. It doesn't appear as if you have a basic understanding of C++ at this time. But, best of luck and hope I could help!