C++ Error: Line 1440 Expression: string subscript out of range - c++

The program builds and runs, however after entering the first integer and pressing enter then the error pop up box appears, then after pressing ignore and entering the second integer and pressing enter the pop up box appears and after pressing ignore it returns the correct answer. I am at my wits end with this can somebody help me fix the pop up box thing.
#include "stdafx.h"
#include <iostream>
#include <cctype>
#include <string>
using namespace std;
#define numbers 100
class largeintegers {
public:
largeintegers();
void
Input();
void
Output();
largeintegers
operator+(largeintegers);
largeintegers
operator-(largeintegers);
largeintegers
operator*(largeintegers);
int
operator==(largeintegers);
private:
int integer[numbers];
int len;
};
void largeintegers::Output() {
int i;
for (i = len - 1; i >= 0; i--)
cout << integer[i];
}
void largeintegers::Input() {
string in;
int i, j, k;
cout << "Enter any number:";
cin >> in;
for (i = 0; in[i] != '\0'; i++)
;
len = i;
k = 0;
for (j = i - 1; j >= 0; j--)
integer[j] = in[k++] - 48;
}
largeintegers::largeintegers() {
for (int i = 0; i < numbers; i++)
integer[i] = 0;
len = numbers - 1;
}
int largeintegers::operator==(largeintegers op2) {
int i;
if (len < op2.len) return -1;
if (op2.len < len) return 1;
for (i = len - 1; i >= 0; i--)
if (integer[i] < op2.integer[i])
return -1;
else if (op2.integer[i] < integer[i]) return 1;
return 0;
}
largeintegers largeintegers::operator+(largeintegers op2) {
largeintegers temp;
int carry = 0;
int c, i;
if (len > op2.len)
c = len;
else
c = op2.len;
for (i = 0; i < c; i++) {
temp.integer[i] = integer[i] + op2.integer[i] + carry;
if (temp.integer[i] > 9) {
temp.integer[i] %= 10;
carry = 1;
} else
carry = 0;
}
if (carry == 1) {
temp.len = c + 1;
if (temp.len >= numbers)
cout << "***OVERFLOW*****\n";
else
temp.integer[i] = carry;
} else
temp.len = c;
return temp;
}
largeintegers largeintegers::operator-(largeintegers op2) {
largeintegers temp;
int c;
if (len > op2.len)
c = len;
else
c = op2.len;
int borrow = 0;
for (int i = c; i >= 0; i--)
if (borrow == 0) {
if (integer[i] >= op2.integer[i])
temp.integer[i] = integer[i] - op2.integer[i];
else {
borrow = 1;
temp.integer[i] = integer[i] + 10 - op2.integer[i];
}
} else {
borrow = 0;
if (integer[i] - 1 >= op2.integer[i])
temp.integer[i] = integer[i] - 1 - op2.integer[i];
else {
borrow = 1;
temp.integer[i] = integer[i] - 1 + 10 - op2.integer[i];
}
}
temp.len = c;
return temp;
}
largeintegers largeintegers::operator*(largeintegers op2) {
largeintegers temp;
int i, j, k, tmp, m = 0;
for (i = 0; i < op2.len; i++) {
k = i;
for (j = 0; j < len; j++) {
tmp = integer[j] * op2.integer[i];
temp.integer[k] = temp.integer[k] + tmp;
temp.integer[k + 1] = temp.integer[k + 1] + temp.integer[k] / 10;
temp.integer[k] %= 10;
k++;
if (k > m) m = k;
}
}
temp.len = m;
if (temp.len > numbers) cout << "***OVERFLOW*****\n";
return temp;
}
using namespace std;
int main() {
int c;
largeintegers num1, num2, result;
num1.Input();
num2.Input();
num1.Output();
cout << " + ";
num2.Output();
result = num1 + num2;
cout << " = ";
result.Output();
cout << "\n\n";
num1.Output();
cout << " - ";
num2.Output();
result = num1 - num2;
cout << " = ";
result.Output();
cout << "\n\n";
num1.Output();
cout << " * ";
num2.Output();
result = num1 * num2;
cout << " = ";
result.Output();
cout << "\n\n";
c = num1 == num2;
num1.Output();
switch (c) {
case -1:
cout << " is less than ";
break;
case 0:
cout << " is equal to ";
break;
case 1:
cout << " is greater than ";
break;
}
num2.Output();
cout << "\n\n";
system("pause");
}

It seems you are falling victim to the difference between C-style strings and C++ strings. C-style strings are a series of chars followed by a zero (or null) byte. C++ strings are objects that contain a series of characters (usually char, but eventually this will be an assumption you should break) and that know their own length. C++ strings can contain null bytes in the middle of themselves without problem.
To loop through all of the characters of a C++-style string, you can do one of a number of things:
You can use the .size() or .length() members of a string variable to find the number of characters in it, as in for (int i=0; i<str.size(); i++) { char c = str[i];
You can use .begin() and .end() to get iterators to the beginning and end of the string, respectively. A for loop in the form for (std::string::iterator it=str.begin(); it!=str.end(); ++it) will loop you through the members of the string by accessing *it.
If you're using C++11, you can use the for loop construct as follows: for (auto c: str) where c will be of the type of a character of the string str.
In the future, to solve problems like these, you can try using the debugger to see what happens when your program crashes or hits an exception. You likely would find that inside of largeintegers::Input() you running into either a memory access violation or some other problem.
Finally, as a future-looking criticism, you should not use C-style arrays (where you say int integer[ numbers ];) in favor of using C++-style containers, such as vector. A vector is a series of objects (such as ints) that can expand as needed.

Related

I'm having problems with Project Euler #8

Here is my code for Project Euler #8. It reads the 1000-digit number from a file by reading each character, and then converting that to an integer before storing it into an array. I then intended on using loops to read groupings of 13 digits, 0-12, 1-13, 2-14, etc. And multiplying them. If the result is larger than the previous largest one, it is stored into num2.
#include <iostream>
#include <fstream>
using namespace std;
int num1=1, num2;
int main(){
int digitArray[1000];
char ctemp;
int itemp;
ifstream myfile;
myfile.open("1000 digit number.txt");
if(myfile.is_open()){
for(int i=0; i < 1000; i++){
myfile >> ctemp;
itemp = ctemp - '0';
digitArray[i] = itemp;
}
}
myfile.close();
for(int i = 0; i < 1000; i++){
int j = i;
while(j != (i+13)){
num1 *= digitArray[j];
j++;
if(j == 1000){
break;
}
}
if(num1 > num2){
num2 = num1;
} else {}
}
cout << num2 << endl;
return 0;
}
This code outputs the value 5000940, which is not the correct answer. Help?
num1 is not initialized to 1 for every 13 contiguous numbers. Also check the break condition before any out of bound index is accessed.
for(int i = 0; i < 1000; i++){
int j = i;
num1=1;
while(j != (i+13)){
if(j == 1000){
break;
}
num1 *= digitArray[j];
j++;
}
if(num1 > num2){
num2 = num1;
}
}
Streamlining the algorithm I came up with this:
#include <iostream>
#include <string>
#include <cstdint>
int main(){
std::string input;
// std::cin >> input;
input = "1101111111111133111111111111122";
uint64_t prod = 1;
uint64_t m = 0;
size_t count = 0;
for (auto p = input.begin(); p != input.end(); ++p) {
prod *= *p - '0';
if (prod == 0) {
prod = 1;
count = 0;
} else {
if (count++ >= 13) {
prod /= *(p - 13) - '0';
}
if ((count >= 13) && (prod > m)) m = prod;
}
}
std::cout << "max = " << m << std::endl;
}
The approach uses a sliding window updating the product from digit to digit. It starts with a window size of 0 and grows it to 13 before doing that and every time a '0' is seen the window size is reset to grow again.
Here is what worked:
#include <iostream>
#include <fstream>
using namespace std;
int main(){
int digitArray[1000];
char ctemp;
int itemp;
ifstream myfile;
myfile.open("1000 digit number.txt");
if(myfile.is_open()){
for(int i=0; i < 1000; i++){
myfile >> ctemp;
itemp = ctemp - '0';
digitArray[i] = itemp;
}
}
myfile.close();
long num2;
for(int i = 0; i < 1000; i++){
int j = i;
long num1 = 1;
while(j != (i+13)){
if(j == 1000){
break;
}
num1 *= digitArray[j];
j++;
}
cout << endl;
if(num1 > num2){
num2 = num1;
} else {}
}
cout << num2 << endl;
return 0;
}
Needed to make num2 a long, moved the break up, and initialized num1 inside of the for loop instead of outside. Honestly didn't expect to need a value that large. Embarrassing but whatever. Thanks for the help.

Visual C++ assert- String subscript out of range

My program is a solution for the Day 6 question in Advent of Code 2015. I get an error when I use "Start Without Debugging" and enter the puzzle input in the output window.The image contains the exact error I received. The error is related to "string subscript out of range". I would like help in resolving this error.
const int r = 1000;//global variable
const int c = 1000;//global variable
int lights[r][c];//global array
void instruction(string inp)//extracting OFF, ON, or toggle indication from the instruction
{
int* loc;
int coord[4] = { 0 };
char cond = inp[7];
loc = &coord[3];
switch (cond)
{
case 'f':
coordinates(loc, inp);
execute(coord, cond);
break;
case 'n':
coordinates(loc, inp);
execute(coord, cond);
break;
default:
coordinates(loc, inp);
execute(coord, cond);
break;
}
}
void coordinates(int* loc, string inp)//extracting coordinates from the instruction
{
int i, k = 0, l;
l = inp.length()-1;
for (i = l; inp[i] != ','; i--)
{
*loc += (inp[i]-'0') * pow(10,k);
k++;
}
i--;
loc--;
k = 0;
for (; inp[i] != ' '; i--)
{
*loc += (inp[i]-'0') * pow(10,k);
k++;
}
i = i - 9;
loc--;
k = 0;
for (; inp[i] != ','; i--)
{
*loc += (inp[i]-'0') * pow(10,k);
k++;
}
i--;
loc--;
k = 0;
for (; inp[i] != ' '; i--)
{
*loc += (inp[i]-'0') * pow(10,k);
k++;
}
}
void execute(int coord[], char cond)
{
int i, j;
for (i = coord[0]; i <= coord[2]; i++)
{
for (j = coord[1]; j <= coord[3]; j++)
{
if (cond == 'f')
lights[i][j] &= 0;
else if (cond == 'n')
lights[i][j] |= 1;
else
lights[i][j] = ~lights[i][j];
}
}
}
int main()
{
int i, j, k, count = 0;
string inp;
for (i = 0;;i++)
{
cout << "Enter an instruction" << endl;
cin >> inp;
if (inp != "xx")//To manually move to counting the number of lights turned ON
instruction(inp);
else
{
for (j = 0; j < r; j++)
{
for (k = 0; k < c; k++)
{
if (lights[j][k])
count++;
}
}
cout << endl << "Number of lights lit " << count;
break;
}
}
return 0;
}
The problem is most likely this loop (from the coordinates function):
l = inp.length()-1;
for (i = l; inp[i] != ','; i--)
{
*loc += int(inp[i]) * (10 ^ k);
k++;
}
In the very first iteration of the loop then i will be equal to l which is the length of the string, which is out of bounds.
You also don't check if you go out of bounds in the second direction (i becomes negative). You have this problem in all your loops in the coordinates function.
On another note, casting a character to int will not convert a digit character to its corresponding integer value.
Assuming ASCII encoding (the most common encoding available) then the character '2' (for example) will have the integer value 50.
Also the ^ operator it bitwise exclusive OR, not any kind of "power" or "raises" operator. It seems you could need to spend some more times with some of the basics of C++.

exit from recursive void method in c++

I have a recursive void method which is written in c++. How can I exit from this recursive method when I get my needed value.
#include<bits/stdc++.h>
using namespace std;
int a[25];
char x[25];
int n, m ;
string s;
void go(int pos)
{
if(pos == n - 1)
{
int suma = a[0];
for(int i = 0 ; i < n - 1;i++)
{
if(x[i] == '+')suma += a[i + 1];
else suma -= a[i + 1];
}
//here I need hint how to close this method when suma will equal to m
//if(suma == x) here I should break this method
return ;
}
x[pos] = '+';
go(pos+1);
x[pos] = '-';
go(pos+1);
}
main()
{
cin >> n >> m;
for(int i = 0 ; i < n;i++)
cin >> a[i];
go(0);
for(int i = 0 ; i < n- 1;i++)
cout << x[i]<<" ";
}
I need to hint how to break void method when my summa will equal to x data everything was declared please do you know some hint for closing this method and I should get value of x arrays.
Throw where you have found your result, and catch at the initial call site
#include <string>
#include <iostream>
int a[25];
char x[25];
int n, m ;
std::string s;
struct result_found{};
void go(int pos)
{
if(pos == n - 1)
{
int suma = a[0];
for(int i = 0; i < n - 1; i++)
{
if(x[i] == '+')suma += a[i + 1];
else suma -= a[i + 1];
}
if (suma == m)
throw result_found{};
}
x[pos] = '+';
go(pos+1);
x[pos] = '-';
go(pos+1);
}
main()
{
std::cin >> n >> m;
for(int i = 0 ; i < n;i++)
std::cin >> a[i];
try {
go(0);
}
catch (result_found&) {}
for(int i = 0 ; i < n- 1;i++)
std::cout << x[i] << " ";
}
You may use an 'static bool' flag on the method.
static fields on functions keep their value between several functions calls.
void go(int pos)
{
static bool found=false;
if (found) return;
//rest of your code here...
//of course when you found what are you searching, do found = true;
}

C++ - Finding x Factor of a math expression

I'm trying to get the x factor of an input math expression, but it seems buggy.
Here is my code:
#include<iostream>
#include<math.h>
using namespace std;
int main(){
char a[100];
int res = 0; // final answer
int temp = 0; // factor of the x we are focused on - temporarily
int pn = 0; // power of 10 - used for converting digits to number
int conv; // used for conversion of characters to int
cout<< "Enter a: ";
cin>> a; //input expression
for(int i=0; i<100; i++){
// checking if the character is x - then get the factor
if(a[i]=='x'){
for(int j=1; j<=i+1; j++){
conv = a[i-j] - '0'; // conversion
if(conv>=0 && conv<=9){ // check if the character is a number
temp = temp + conv*pow(10, pn); // temporary factor - using power of 10 to convert digit to number
pn++; // increasing the power
}
else{
if(a[i-j]=='-'){
temp = -temp; // check if the sign is - or +
}
break;
}
if(i-j==0){
break;
}
}
res = res+temp; // adding the x factor to other ones
pn = 0;
temp = 0;
}
}
cout<< res;
return 0;
}
It doesn't work for some inputs, for example:
100x+3x gives 102 and 3x+3997x-4000x gives -1
But works for 130x and 150x!
Is there a problem with my code, or is there an easier way to do this?
I think you're not parsing the +. There may be some other problem I can't see in the original code, probably not. Here's the X-File:
int main(){
char a[100];
int res(0);
cout << "Enter a: ";
cin >> a;
for(int i = 0; i < 100; i++){
if(a[i] == 'x'){
int temp(0);
int pn(0);
for(int j = 1; j <= i; j++){
int conv = a[i - j] - '0';
if(conv >= 0 && conv <= 9){
temp += conv*pow(10, pn);
pn++;
} else if(a[i - j] == '-') {
temp = -temp;
break;
} else if(a[i - j] == '+') {
break;
} else {
// what to do...
}
}
res += temp;
}
}
cout << res;
return 0;
}

Strange behaviour of pointers in C++

#include <cstdlib>
#include <iostream>
#include <Math.h>
#include <algorithm>
#include <string>
#include <iterator>
#include <iostream>
#include <vector> // std::vector
using namespace std;
int stepCount, i, x, y, z, j, k, array1Size, array2Size, tester, checker;
int numstring[10] = { 0,1,2,3,4,5,6,7,8,9 };
int numstringTest[10] = { 0,1,2,3,4,5,6,7,7,9 };
int* numbers;
int* differentNumbers;
int* p;
int* otherNumbers;
void stepCounter(int a) {
// determines the step number of the number
if (a / 10 == 0)
stepCount = 1;
else if (a / 100 == 0)
stepCount = 2;
else if (a / 1000 == 0)
stepCount = 3;
else if (a / 10000 == 0)
stepCount = 4;
else if (a / 100000 == 0)
stepCount = 5;
else if (a / 1000000 == 0)
stepCount = 6;
else if (a / 10000000 == 0)
stepCount = 7;
else if (a / 100000000 == 0)
stepCount = 8;
else if (a / 1000000000 == 0)
stepCount = 9;
}
void stepIndicator(int b) {
// indicates each step of the number and pass them into array 'number'
stepCounter(b);
numbers = new int[stepCount];
for (i = stepCount; i>0; i--) {
//
/*
x = (round(pow(10,stepCount+1-i)));
y = (round(pow(10,stepCount-i)));
z = (round(pow(10,stepCount-i)));
*/
x = (int)(pow(10, stepCount + 1 - i) + 0.5);
y = (int)(pow(10, stepCount - i) + 0.5);
numbers[i - 1] = (b%x - b%y) / y;
}
}
int sameNumberCheck(int *array, int arraySize) {
//checks if the array has two or more of same integer inside return 1 if same numbers exist, 0 if not
for (i = 0; i<arraySize - 1; i++) {
//
for (j = i + 1; j<arraySize; j++) {
//
if (array[i] == array[j]) {
//
return 1;
}
}
}
return 0;
}
void getDifferentNumbers(int* array, int arraySize) {
//
k = 0;
j = 0;
checker = 0;
otherNumbers = new int[10 - arraySize]; //exact number of other numbers is 10 - numbers we have
for (i = 0; i<10; i++) {
if ((i>0)&(checker = 0)) {
k++;
otherNumbers[k - 1] = i - 1;
}
//
checker = 0;
for (j = 0; j<arraySize; j++) {
//
p = array + j;
cout << *p << endl; //ilkinde doğru sonra yanlış yapıyor?!
if (*p = i) {
checker++;
}
}
}
}
int main(int argc, char *argv[])
{
stepCounter(999999);
cout << stepCount << endl;
stepIndicator(826424563);
for (j = 0; j<9; j++) {
//
cout << numbers[j] << endl;
}
cout << sameNumberCheck(numstringTest, 10) << " must be 1" << endl;
cout << sameNumberCheck(numstring, 10) << " must be 0" << endl;
cout << endl;
getDifferentNumbers(numstringTest, 10);
cout << endl;
cout << endl << otherNumbers[0] << " is the diff number" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Hi, my problem is with pointers actually. You will see above, function getDifferentNumbers. It simply does a comparement if in any given array there are repeated numbers(0-9). To do that, I passed a pointer to the function. I simply do the comparement via pointer. However, there is a strange thing here. When I execute, first time it does correct, but secon time it goes completely mad! This is the function:
void getDifferentNumbers(int* array, int arraySize) {
//
k = 0;
j = 0;
checker = 0;
otherNumbers = new int[10 - arraySize]; //exact number of other numbers is 10 - numbers we have
for (i = 0; i<10; i++) {
if ((i>0)&(checker = 0)) {
k++;
otherNumbers[k - 1] = i - 1;
}
//
checker = 0;
for (j = 0; j<arraySize; j++) {
//
p = array + j;
cout << *p << endl; //ilkinde doğru sonra yanlış yapıyor?!
if (*p = i) {
checker++;
}
}
}
}
and this is the array I passed into the function:
int numstringTest[10] = {0,1,2,3,4,5,6,7,7,9};
it should give the number 7 in otherNumbers[0], however it does not. And I do not know why. I really can not see any wrong statement or operation here. When I execute, it first outputs the correct values of
numstringTest: 1,2,3,4,5,6,7,7,9
but on next 9 iteration of for loop it outputs:
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888
You have some basic problems in your code.
There are multiple comparisons that are not really comparisons, they're assignments. See the following:
if((i>0) & (checker=0)){
and
if(*p = i){
In both cases you're assigning values to the variables, not comparing them. An equality comparison should use ==, not a single =. Example:
if (checker == 0) {
Besides that, you're using & (bitwise AND) instead of && (logical AND), which are completely different things. You most likely want && in your if statement.
I've just noticed this:
getDifferentNumbers(numstringTest, 10);
and in that function:
otherNumbers = new int[10 - arraySize];
which doesn't seem right.