Why my program terminate calling the KERNEL32!FileTimeToSystemTime ()? - c++

When I debug, the program collapse in the 3rd line of subset().
There are two picture of running the program and debugging...
#include <iostream>
#include <cmath>
#include <cstdio>
#include <stack>
using namespace std;
int c[6];
char s[101];
int end, yes;
stack<char> sstk;
stack<int> nstk;
int toInt(char ch)
{
int temp;
switch(ch)
{
case 'p': temp = c[0];
break;
case 'q': temp = c[1];
break;
case 'r': temp = c[2];
break;
case 's': temp = c[3];
break;
case 't': temp = c[4];
break;
default:
cout<<"Char incorrect :"<<endl;
}
return temp;
}
int oper(int x, int y, char ch)
{
switch(ch)
{
case 'K':
if(1 == x && 1 == y)
return 1;
else
return 0;
case 'A':
if(0 == x && 0 == y)
return 0;
else
return 1;
case 'C':
if(1 == x && 0 == y)
return 0;
else
return 1;
case 'E':
if(x == y)
return 1;
else
return 0;
default:
cout<<"Operation error"<<endl;
return -1;
}
}
bool isOper(char ch)
{
switch(ch)
{
case 'K': case 'A': case 'N': case 'C': case 'E':
return true;
default:
return false;
}
}
int isTau()
{
char a, b, p, t;
int f; //f==1 means the char was asigned
p = s[0]; cout<<"A time p="<<p<<endl;
if(p == 0)
return -1;
if(!isOper(p) )
return 0;
int i = 1;
while((t=s[i++]) != '!')
{ cout<<t<<endl;
if(isOper(t) ) //If the t char is operator, push previous opertator
{
if(1 == f) //and push the a operand if there is one
nstk.push(a);
sstk.push(p);
p = t; //replace the p with t
f = 0;
continue;
}
int num = toInt(t); //If t is not operatand, trans it to int
if(p == 'N') //To operate either there is an N or f==1(a, b, p)
{
b = (num == 1 ? 0 : 1);
}
if(1 == f)
{
b = oper(a, num, p);
}
else
{
a = num;
f = 1;
continue;
}
while(!sstk.empty() )
{
p = sstk.top();
if('N' == p)
{
b = (b == 1 ? 0 : 1);
sstk.pop();
continue;
}
a = nstk.top();
b = oper(a, b, p);
nstk.pop();
sstk.pop();
}
a = b;
f = 0;
}
if(1 == a)
return 1;
else
return 0;
}
void subset(int n,int *A, int cur)
{
for(int i=0; i<cur; i++)
{ cout<<A[i]<<" ";
c[A[i]] = 1;
} cout<<endl;
if(cur != 0)
{
int t = isTau(); //cout<<"Is Tas: "<<t<<endl;
if(t == -1)
{
end = 1;
return;
}
if(t == 0)
yes = 0;
}
int s = cur ? A[cur-1]+1 : 0;
for(int i=s; i<n; i++)
{
A[cur] = i;
subset(n, A, cur+1);
if(end == 1)
return;
}
}
int main()
{
freopen("input.txt","r",stdin);
do
{ cout<<"Loop : "<<endl;
int i;
char t;
for(i=0; (t=getchar() ) != '\n'; i++)
{
s[i] = t;
}
s[i] = '!';
int *a;
subset(5,a,0); cout<<"what?";
if(yes == 1)
cout<<"tautology"<<endl;
else
cout<<"not"<<endl;
}while(end == 0);
return 0;
}
Running
Call stack

int *a;
subset(5,a,0); cout<<"what?";
Here a is defined as a pointer to integer(s) but is never initialized. Then it is passed to subset which attempts to dereference it...
cout<<A[i]<<" ";
...which results in UB (undefined behavior). Everything that happens from there on, including crashing, is a possible outcome of UB.
You can either point a to an allocated buffer before using it:
int *a = new int[5]; // uninitialized, use instead 'new int[5]();' to initialize to all-0
subset(5,a,0); cout<<"what?";
// ...
// remember to 'delete [] a;' when no longer used
Or you can change a to a local array:
int a[5]; // uninitialized, use instead 'int a[5] = { 0 };` to initialize to all-0
subset(5,a,0); cout<<"what?";

Related

Overwrite the elements in a vector without specifying specific elements

I am making a calculator that accepts multiple operators at once. I have a vector pair that stores the position of operators, and the type of operator. The vector must be updated after each loop as the previous positions are no longer valid due to the result replacing a part of the input string.
I've attempted to use clear() so that it starts from the beginning again, but that results in Expression: vector iterators incompatible. I don't think I can use std::replace since the number of operators in the string changes after each loop. Is there a way to just have it start from the beginning again and overwrite any existing elements?
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::cout << "C++ Calculator" << std::endl;
while (true) //runs forever with loop
{
std::string input;
std::getline(std::cin, input);
//erases whitespace
int inp_length = input.length();
for (int i = inp_length - 1; i >= 0; --i)
{
if (input[i] == ' ')
input.erase(i, 1);
}
std::vector<std::pair<int, char>> oper_pvec;
int vec_pos = 0;
//finds the position of operators and type
for (std::string::iterator i = input.begin(); i != input.end(); ++vec_pos, ++i)
{
switch (*i)
{
case 'x':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, 'x'));
break;
}
case '/':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, '/'));
break;
}
case '+':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, '+'));
break;
}
case '-':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, '-'));
break;
}
}
}
//declarations before loop to make sure they're all able to be accessed, will probably change later
int loper_pos = 0; //must be set 0 since there's no left operator at first
int roper_pos;
double lnum; //left number
double rnum; //right number
char loper; //left operator
char roper; //right operator
int pos = -1; //position of loop, needs to be -1 since it increments it each time
std::string holder = input; //copy of input
auto op = oper_pvec.begin();
while (op != oper_pvec.end())
{
op = oper_pvec.begin();
++pos; //position of loop
int key = std::get<0>(*op); //gets first value from vector pair
char val = std::get<1>(*op); //gets second value from vector pair
//gets previous/next vector pairs
std::vector<std::pair<int, char>>::iterator prev_op = oper_pvec.begin();
std::vector<std::pair<int, char>>::iterator next_op = oper_pvec.end();
if (op != oper_pvec.begin()) prev_op = std::prev(op);
if (op != oper_pvec.end()) next_op = std::next(op);
//extracts the value of pairs
if (pos > 0)
{
loper_pos = std::get<0>(*prev_op);
loper = std::get<1>(*prev_op);
}
if (pos == oper_pvec.size() - 1) roper_pos = oper_pvec.size();
else
{
roper_pos = std::get<0>(*next_op);
roper = std::get<1>(*next_op);
}
//replaces numbers and etc with product, only multiplication for now
switch (val)
{
case 'x':
{
int lnum_start = loper_pos + 1;
if (loper_pos == 0) lnum_start = 0;
int lnum_len = key - (loper_pos + 1);
if (loper_pos == 0) lnum_len = key;
lnum = std::stod(input.substr(lnum_start, lnum_len));
int rnum_start = key + 1;
int rnum_len = (roper_pos - 1) - key;
rnum = std::stod(input.substr(rnum_start, rnum_len));
double prod = lnum * rnum;
std::string to_string = std::to_string(prod);
input.replace(loper_pos, roper_pos, to_string);
break;
}
}
/////////////////////////////////problem area////////////////////////////////////////
//clears the vector and then finds the operators again
oper_pvec.clear();
int vpos = 0;
for (std::string::iterator it = input.begin(); it != input.end(); ++vpos, ++it)
{
if (vpos == input.length())
{
vpos = 0;
break;
}
switch (*it)
{
case 'x':
{
oper_pvec.push_back(std::pair<int, char>(vpos, 'x'));
break;
}
case '/':
{
oper_pvec.push_back(std::pair<int, char>(vpos, '/'));
break;
}
case '+':
{
oper_pvec.push_back(std::pair<int, char>(vpos, '+'));
break;
}
case '-':
{
oper_pvec.push_back(std::pair<int, char>(vpos, '-'));
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////
}
//converts to double then prints on screen
double out = std::stod(input);
std::cout << out << std::endl;
}
}
Not really the answer to the title but instead of trying to overwrite the vector I just continued to use clear() and changed the while loop to oper_pvec.size() != 0.
(Full code since I had to change quite a few things to get it to work properly)
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::cout << "C++ Calculator" << std::endl;
while (true) //runs forever with loop
{
std::string input;
std::getline(std::cin, input);
//erases whitespace
int inp_length = input.length();
for (int i = inp_length - 1; i >= 0; --i)
{
if (input[i] == ' ')
input.erase(i, 1);
}
std::vector<std::pair<int, char>> oper_pvec;
int vec_pos = 0;
//finds the position of operators and type
for (std::string::iterator i = input.begin(); i != input.end(); ++vec_pos, ++i)
{
switch (*i)
{
case 'x':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, 'x'));
break;
}
case '/':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, '/'));
break;
}
case '+':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, '+'));
break;
}
case '-':
{
oper_pvec.push_back(std::pair<int, char>(vec_pos, '-'));
break;
}
}
}
//declarations before loop to make sure they're all able to be accessed, will probably change later
int loper_pos = 0; //must be set 0 since there's no left operator at first
int roper_pos;
double lnum; //left number
double rnum; //right number
char loper; //left operator
char roper; //right operator
int pos = -1; //position of loop, needs to be -1 since it increments it each time
std::string holder = input; //copy of input
std::vector<std::pair<int, char>> vec_copy = oper_pvec;
auto op = oper_pvec.begin();
while (oper_pvec.size() != 0)
{
op = oper_pvec.begin();
++pos; //position of loop
int key = std::get<0>(*op); //gets first value from vector pair
char val = std::get<1>(*op); //gets second value from vector pair
//gets previous/next vector pairs
std::vector<std::pair<int, char>>::iterator prev_op = oper_pvec.begin();
std::vector<std::pair<int, char>>::iterator next_op = oper_pvec.end();
if (op != oper_pvec.begin()) prev_op = std::prev(op);
if (op != oper_pvec.end()) next_op = std::next(op);
//extracts the value of pairs
if (pos > 0)
{
loper_pos = std::get<0>(*prev_op);
loper = std::get<1>(*prev_op);
}
if (op == oper_pvec.begin()) loper_pos = 0;
if (oper_pvec.size() == 1) roper_pos = input.length();
else
{
roper_pos = std::get<0>(*next_op);
roper = std::get<1>(*next_op);
}
//replaces numbers and etc with product, only multiplication for now
switch (val)
{
case 'x':
{
int lnum_start = loper_pos + 1;
if (lnum_start == 1) lnum_start = 0;
if (loper_pos > 0)
if (isdigit(input[loper_pos - 1])) lnum_start = 0;
int lnum_len = key - (loper_pos + 1);
if (lnum_start == 0)
{
if (key == 1) lnum_len = 1;
else lnum_len = key - 1;
}
lnum = std::stod(input.substr(lnum_start, lnum_len));
int rnum_start = key + 1;
int rnum_len = (roper_pos - 1) - key;
rnum = std::stod(input.substr(rnum_start, rnum_len));
double prod = lnum * rnum;
std::string to_string = std::to_string(prod);
input.replace(loper_pos, roper_pos, to_string);
break;
}
}
//clears the vector and then finds the operators again
oper_pvec.clear();
int vpos = 0;
for (std::string::iterator it = input.begin(); it != input.end(); ++vpos, ++it)
{
if (vpos == input.length())
{
vpos = 0;
break;
}
switch (*it)
{
case 'x':
{
oper_pvec.push_back(std::pair<int, char>(vpos, 'x'));
break;
}
case '/':
{
oper_pvec.push_back(std::pair<int, char>(vpos, '/'));
break;
}
case '+':
{
oper_pvec.push_back(std::pair<int, char>(vpos, '+'));
break;
}
case '-':
{
oper_pvec.push_back(std::pair<int, char>(vpos, '-'));
break;
}
}
}
}
//converts to double then prints on screen
double out = std::stod(input);
std::cout << out << std::endl;
}
}

C++ vector assignments

My program should read input as an integer for the length followed by (sufficiently) parenthesized floats and simple operators and output the value of the expression. For example, if the input were 11 1 + 2 ^ 3 / 4 * 5 - 6, the result should be equal to (1 + (((2 ^ 3) / 4) * 5)) - 6, or 5. However, even when I input 5 1 + 2 + 3, the output is 5 instead of 6. I think this might be because of the many vector assignments, in particular the marked line (I found this while debugging).
My code (sorry if it is not self explanatory):
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
float op(char op, float x, float y)
{
switch (op)
{
case '+':
{
return x+y;
break;
}
case '-':
{
return x-y;
break;
}
case '*':
{
return x*y;
break;
}
case '/':
{
return x/y;
break;
}
case '^':
{
return pow(x,y);
break;
}
default:
{
cout << "Error: bad input ";
return 0;
}
}
}
float nopars(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int len = stackl, opsrr = opsr;
vector<string> nstack, nnstack;
vector<char> nops = ops, nnops;
nstack = stack;
while (opsrr != 0)
{
string s1 (1, nops[0]);
for (int i = 0; i < len; i++)
{
if (nstack[i] == s1)
{
for (int j = 0; j < len - 2; j++)
{
nnstack = {};
if (j == i-1)
{
nnstack.push_back(to_string(op(nops[0], stof(nstack[i-1]), stof(nstack[i+1]))));
}
else if (j < i-1)
{
nnstack.push_back(nstack[j]);
}
else if (j > i-1)
{
nnstack.push_back(nstack[j+2]);
}
}
len = len - 2;
nstack = nnstack; //I think this is wrong?
i--;
}
}
nnops = {};
for (int i = 0; i < opsr-1; i++)
{
nnops.push_back(nops[i+1]);
}
opsrr--;
nops = nnops;
}
return stof(nstack[0]);
}
float all(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int t1 = 0, t2 = 0;
int len = stackl;
int nprs;
vector<string> nstack, nnstack, nstck;
nstack = stack;
while (true)
{
nprs = 0;
for (int i = 0; i < len; i++)
{
if (nstack[i] == "(")
{
nprs = 1;
t1 = i;
}
else if (nstack[i] == ")")
{
nprs = 1;
t2 = i;
nstck = {};
for (int j = t1 + 1; j < t2; j++)
{
nstck.push_back(nstack[j]);
}
for (int j = 0; j < len - t2 + t1; j++)
{
if (j == t1)
{
nnstack.push_back(to_string(nopars(nstck, t2-t1-1, ops, opsr)));
}
else if (j < t1)
{
nnstack.push_back(nstack[j]);
}
else if (j > t1)
{
nnstack.push_back(nstack[j+t2-t1]);
}
}
len = len - t2 + t1;
break;
}
}
if (nprs == 0)
{
break;
}
nstack = nnstack;
}
return nopars(nstack, len, ops, opsr);
}
void calculate()
{
vector<string> stack;
int stackl;
string t;
cin >> stackl;
for (int i = 0; i < stackl; i++)
{
cin >> t;
stack.push_back(t);
}
cout << all(stack, stackl, {'^', '/', '*', '-', '+'}, 5);
}
int main()
{
calculate();
return 0;
}
A binary recurrent LL parser
#include <iostream>
#include <string>
#include <sstream>
#include <functional>
#include <iterator>
#include <cmath>
#include <map>
using namespace std;
using T = float;
map< int, map<std::string, std::function<T(const T&, const T&)> > > m_foo =
{ {1, { { "+", std::plus<T>() }, { "-", std::minus<T>() } } },
{2, { { "*", std::multiplies<T>() }, { "/", std::divides<T>() } } },
{3, { { "^", powf } } } };
T calc_ll(istream_iterator<string>& t, int level) {
if ( !m_foo.contains(level) ) return std::stof(*t++);
auto result = calc_ll(t, level+1);
auto l = m_foo[level];
while ( l.find(*t) != l.end() ) {
auto foo = l.find(*t)->second;
result = foo(result, calc_ll(++t, level+1) );
}
return result;
}
int main()
{
std::stringstream ss(std::string("1 + 2 ^ 3 / 4 * 5 - 6"));
auto t = istream_iterator<string>(ss);
cout << "result : " << calc_ll( t, 1 );
return 0;
}
link https://godbolt.org/z/9vPMGn
It seems the error is in the unintentionally repeated declaration nnstack = {}.
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
float op(char op, float x, float y)
{
switch (op)
{
case '+':
{
return x+y;
break;
}
case '-':
{
return x-y;
break;
}
case '*':
{
return x*y;
break;
}
case '/':
{
return x/y;
break;
}
case '^':
{
return pow(x,y);
break;
}
default:
{
cout << "Error: bad input ";
return 0;
}
}
}
float nopars(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int len = stackl, opsrr = opsr;
vector<string> nstack, nnstack;
vector<char> nops = ops, nnops;
nstack = stack;
while (opsrr != 0)
{
string s1 (1, nops[0]);
for (int i = 0; i < len; i++)
{
if (nstack[i] == s1)
{
nnstack = {}; //this was missing
for (int j = 0; j < len - 2; j++)
{
//nnstack = {}; //this was misplaced
if (j == i-1)
{
nnstack.push_back(to_string(op(nops[0], stof(nstack[i-1]), stof(nstack[i+1]))));
}
else if (j < i-1)
{
nnstack.push_back(nstack[j]);
}
else if (j > i-1)
{
nnstack.push_back(nstack[j+2]);
}
}
len = len - 2;
nstack = nnstack;
i--;
}
}
nnops = {};
for (int i = 0; i < opsr-1; i++)
{
nnops.push_back(nops[i+1]);
}
opsrr--;
nops = nnops;
}
return stof(nstack[0]);
}
float all(vector<string> stack, int stackl, vector<char> ops, int opsr)
{
int t1 = 0, t2 = 0;
int len = stackl;
int nprs;
vector<string> nstack, nnstack, nstck;
nstack = stack;
while (true)
{
nprs = 0;
for (int i = 0; i < len; i++)
{
if (nstack[i] == "(")
{
nprs = 1;
t1 = i;
}
else if (nstack[i] == ")")
{
nprs = 1;
t2 = i;
nstck = {};
for (int j = t1 + 1; j < t2; j++)
{
nstck.push_back(nstack[j]);
}
for (int j = 0; j < len - t2 + t1; j++)
{
if (j == t1)
{
nnstack.push_back(to_string(nopars(nstck, t2-t1-1, ops, opsr)));
}
else if (j < t1)
{
nnstack.push_back(nstack[j]);
}
else if (j > t1)
{
nnstack.push_back(nstack[j+t2-t1]);
}
}
len = len - t2 + t1;
break;
}
}
if (nprs == 0)
{
break;
}
nstack = nnstack;
}
return nopars(nstack, len, ops, opsr);
}
void calculate()
{
vector<string> stack;
int stackl;
string t;
cin >> stackl;
for (int i = 0; i < stackl; i++)
{
cin >> t;
stack.push_back(t);
}
cout << all(stack, stackl, {'^', '/', '*', '-', '+'}, 5);
}
int main()
{
calculate();
return 0;
}

invalid types 'int[int]' for array subscript in multidimensional array c++

While doing my course project of card game, i got this error
Invalid types `int[int]' for array subscript'
Here is the code :
#include <iostream>
#include <stdlib.h>
#include <time.h>
int randomize(int, int);
int* generateCardNumber(int[5]);
int* generateCardLogo(int, int[13][4], int[5]);
int* compareCard(int[5], int[5], int[5], int[5], int[13][4]);
int printResult(int[5]);
void showCard(int, int[5], int[5], int[5], int[5]);
void printCard(int[5], int[5]);
using namespace std;
int main()
{
srand(time(NULL));
int player1Number[5], player1Logo[5];
int *number1, *logo1;
int player2Number[5], player2Logo[5];
int *number2, *logo2;
int cardInfo[13][4];
int **card;
char answer;
do
{
int playerInput;
int d, c, r;
int player1Score, player2Score;
cout<<"Welcome to the card game!"<<endl;
cout<<" Choose player{1: Player 1; 2: Player 2} : ";
cin>>playerInput;
cout<<endl;
do
{
cout<<"Press d to deal card :";
}while(d != 'd');
number1 = generateCardNumber(player1Number);
logo1 = generateCardLogo(1,cardInfo, player1Number);
for (int i = 0; i<5; i++)
{
cardInfo[player1Number[i]][player1Logo[i]] = 1;
}
number2 = generateCardNumber(player2Number);
logo2 = generateCardLogo(2,cardInfo, player2Number);
for (int i = 0; i<5; i++)
{
cardInfo[player2Number[i]][player2Logo[i]] = 1;
}
showCard(playerInput,player1Number,player1Logo,
player2Number,player2Logo);
do
{
cout<<"Press c to compare card :";
}while(c != 'c');
*card = compareCard(player1Number,player1Logo,
player2Number,player2Logo,cardInfo);
for (int i = 0; i<5; i++)
{
if(cardInfo[player1Number[i]][player1Logo[i]] = -1)
{
player1Number[i] = -1;
player1Logo[i] = -1;
}
else if(cardInfo[player2Number[i]][player2Logo[i]] = -1)
{
player2Number[i] = -1;
player2Logo[i] = -1;
}
}
showCard(playerInput,player1Number,
player1Logo,player2Number,player2Logo);
do
{
cout<<"Press r to show result :";
}while(r != 'r');
if(playerInput == 1)
{
cout<<"Player1 (You): ";
player1Score = printResult(player1Number);
cout<<"Player2 (Computer): ";
player2Score = printResult(player2Number);
if(player1Score > player2Score) cout<<"You WIN!"<<endl;
else cout<<"Computer WIN!"<<endl;
}
else if(playerInput == 2)
{
cout<<"Player1 (Computer): ";
player1Score = printResult(player1Number);
cout<<"Player2 (You): ";
player2Score = printResult(player2Number);
if(player2Score > player1Score) cout<<"You WIN!"<<endl;
else cout<<"Computer WIN!"<<endl;
}
cout<<"Do you want to play again? (y/n)"<<endl;
cin>>answer;
}while(answer == 'Y' || answer == 'y');
}
int randomize (int x, int y)
{
return (rand()%y + x);
}
int* generateCardNumber (int numberArray[5])
{
int arrayStoring[13] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i<5; i++)
{
do
{
numberArray[i] = randomize(1,13);
}while (arrayStoring[numberArray[i]] == 1);
arrayStoring[numberArray[i]] = 1;
}
return numberArray;
}
int* generateCardLogo (int turn, int cardInfo[4][13], int player2Number[5])
{
int logoArray[5];
if(turn == 1)
{
for (int i = 0; i<5; i++)
{
logoArray[i] = randomize(1,4);
}
return logoArray;
}
else if(turn == 2)
{
for (int i = 0; i<5; i++)
{
do
{
logoArray[i] = randomize(1,4);
}while (cardInfo[player2Number[i]][logoArray[i]] == 1);
}
return logoArray;
}
}
int** compareCard(int player1Number, int player1Logo, int player2Number, int player2Logo, int cardInfo)
{
for(int i=0; i<5 ; i++)
{
for(int j=0; j<5 ; j++)
{
if(player1Number[i] == player2Number[j])
{
if(player1Logo[i] < player2Logo[j]) cardInfo[player1Number[i]][player1Logo[i]] = -1;
else if(player1Logo[i] > player2Logo[j]) cardInfo[player2Number[i]][player2Logo[i]] = -1;
break;
}
}
}
return cardInfo;
}
int printResult (int playerNumber)
{
int playerScore = 0;
for (int i = 0; i<5; i++)
{
if(playerNumber[i] == -1) break;
else if(playerNumber[i] == 0)
{
playerScore += 15;
cout<<"15 ";
}
else if(playerNumber[i] > 0 && playerNumber[i] < 10 )
{
playerScore += (playerNumber[i] + 1);
cout<< (playerNumber[i] + 1) <<" ";
}
else if(playerNumber[i] >= 10)
{
playerScore += 12;
cout<<"12 ";
}
if(i<4) cout<<"+ ";
else if(i==4)
{
cout<<"= "<<playerScore<<" points";
}
}
return playerScore;
}
void printCard (int numberArray[5], int logoArray[5])
{
for (int i = 0; i<5; i++)
{
switch(numberArray[i])
{
case -1 :
cout<<"<fold> ";
break;
case 0 :
cout<<"Ace ";
break;
case 1 :
cout<<"2 ";
break;
case 2 :
cout<<"3 ";
break;
case 3 :
cout<<"4 ";
break;
case 4 :
cout<<"5 ";
break;
case 5 :
cout<<"6 ";
break;
case 6 :
cout<<"7 ";
break;
case 7 :
cout<<"8 ";
break;
case 8 :
cout<<"9 ";
break;
case 9 :
cout<<"10 ";
break;
case 10 :
cout<<"Jack ";
break;
case 11 :
cout<<"Queen ";
break;
case 12 :
cout<<"King ";
break;
}
switch(logoArray[i])
{
case -1:
break;
case 0:
cout<<"Diamond ";
break;
case 1:
cout<<"Club ";
break;
case 2:
cout<<"Heart ";
break;
case 3:
cout<<"Spade ";
break;
}
}
}
void showCard (int playerInput, int player1Number, int player1Logo, int player2Number, int player2Logo)
{
if(playerInput == 1)
{
cout<<"Player1 (You):"<<endl;
printCard(player1Number, player1Logo);
cout<<"Player2 (Computer):"<<endl;
printCard(player2Number, player2Logo);
}
else if(playerInput == 2)
{
cout<<"Player1 (Computer):"<<endl;
printCard(player1Number, player1Logo);
cout<<"Player2 (You):"<<endl;
printCard(player2Number, player2Logo);
}
}
Honestly, i still newbie at programming. So i didn't know that i can't return a whole array from a function. After searching for clue, i found out that i can use pointer to return an array from function. When i try to fix the code, this error come out and i didn't know what i need to fix.
The error keep appearing when i try to use the array from the function parameter,such as this
if(player1Number[i] == player2Number[j])<br/>
from function
int** compareCard(int player1Number, int player1Logo, int player2Number,
int player2Logo, int cardInfo)
and onward.
Can someone help me figure this out? Correction to the code would be very appreciated. Thankyou very much! (Sorry if my english is bad)
You're declaring compareCard with a bunch of arrays (so int pointers) as parameters:
int* compareCard(int[5], int[5], int[5], int[5], int[13][4]);
Then, however, you're implementing it using integers (not pointers) as parameters:
int** compareCard(int player1Number, int player1Logo, int player2Number, int player2Logo, int cardInfo)
{
for(int i=0; i<5 ; i++)
You're also using them as arrays:
if(player1Logo[i] < player2Logo[j]) cardInfo[player1Number[i]][player1Logo[i]] = -1;
Also, the return type is wrong. You're declaring it as int*, but then implement it as int**. You have to ensure that the signature of your function matches. It looks like taking the signature of the declaration and applying it to the definition should fix this compile time error.
Does your compiler issue any warnings for these function declarations? If not, see if you can set it to be more strict with warnings. Getting the correct warnings for potential errors greatly increases debug efficiency.

Converting Roman Numerals to Int - Getting the Wrong Output - Why?

Here is my code. First, I want to say, I have been experimenting, so if you see unnecessary variables here and there, that's why. But the main part of my code is in the function decimal in my class romanType. When I input certain roman numerals, I am not getting the exact numbers I want and it might be in my logic somewhere in my if/else statements.
By the way, to show how I traverse the string - I do it by reverse traversing. I go from the very end of the string to the very beginning of the string, which I think is easier with roman numerals. By the way, I also made an enum type so I could compare the roman numerals seeing which one is lesser, which one is greater etc. Then I used a map to be able to compare the enum values with the char value.
So the problem: For instance, when I type in CCC, I get 290 instead of 300. If you know what is wrong in my logic, I would greatly appreciate that! Thank you.
Furthermore, I am quite new to programming and would greatly appreciate any stylistic tips or anything I can learn about classes etc that I missed in writing this code? Please let me know what is best. Thank you.
#include <iostream>
#include <string>
#include <map>
using namespace std;
class romanType {
string numeral;
int k;
public:
romanType();
void rnumeral (string b) {numeral = b;}
int decimal(string num, char b, int temp) {
num = "";
enum RomanNumerals {I, V, X, L, C, D, M };
map<char, RomanNumerals> m;
m['I'] = I;
m['V'] = V;
m['X'] = X;
m['L'] = L;
m['C'] = C;
m['D'] = D;
m['M'] = M;
RomanNumerals roman1;
RomanNumerals roman2;
cout << "Please type in your roman numeral:" ;
cin >> num;
for (int i =0; i <num.length()-1; i++){
}
for(long i = num.length()-1; i>=0; i--)
{
b = num[i];
if (islower(b)) b=toupper(b);
roman1 = m[num[i]];
roman2 = m[num[i-1]];
switch(b){
case 'I':
if(num[i] == num.length()-1){
temp += 1;
}
break;
case 'V':
if(roman1 > roman2){
temp += 4;
continue;
}
else {
temp += 5;
}
break;
case 'X':
if(roman1 > roman2){
temp += 9;
continue;
}
else {
temp += 10;
}
break;
case 'L' :
if(roman1 > roman2){
temp += 40;
continue;
}
else {
temp += 50;
}
break;
case 'C':
if(roman1 > roman2){
temp += 90;
continue;
}
else {
temp += 100;
}
break;
case 'D' :
if(roman1 > roman2){
temp += 400;
continue;
}
else {
temp += 500;
}
break;
case 'M':
if(roman1 > roman2){
temp += 900;
continue;
}
else {
temp += 1000;
}
break;
}
}
return temp;
}
};
romanType::romanType () {
numeral = "";
}
int main() {
string k = "";
char b = ' ';
int temp = 0;
romanType type;
type.rnumeral(k);
int c = type.decimal(k, b, temp);
cout << c;
return 0;
}
EDIT: _____________________________________________________________________________
I found the solution to my problem. Here is my new code:
#include <iostream>
#include <string>
#include <map>
using namespace std;
string acceptRN();
class romanType {
string numeral;
int temp2;
int l;
// VARIABLES
public:
romanType();
//DEFAULT CONSTRUCTOR
void getRnumeral (string b)
{
numeral = b;
}
//SETTER
void decimal(string num, int temp, char b) {
num = numeral;
enum RomanNumerals {I, V, X, L, C, D, M };
map<char, RomanNumerals> m;
m['I'] = I;
m['V'] = V;
m['X'] = X;
m['L'] = L;
m['C'] = C;
m['D'] = D;
m['M'] = M;
RomanNumerals roman1;
RomanNumerals roman2;
RomanNumerals roman3;
for(long i = num.length()-1; i>=0; i--)
{
b = num[i];
if (islower(b)) b=toupper(b);
roman1 = m[num[i]];
roman2 = m[num[i-1]];
roman3 = m[num[i+1]];
switch(b){
case 'I':
if( roman3 > roman1 && i != num.length()-1){
continue;
}
else {
temp += 1;
break;
}
case 'V':
if(roman1 > roman2 && i != 0){
temp += 4;
continue;
}
else {
temp += 5;
}
break;
case 'X':
if( roman3 > roman1 && i != num.length()-1)
continue;
if(roman1 > roman2 && i!= 0){
temp += 9;
continue;
}
else {
temp += 10;
}
break;
case 'L' :
if(roman1 > roman2 && i!= 0){
temp += 40;
continue;
}
else {
temp += 50;
}
break;
case 'C':
if( roman3 > roman1 && i != num.length()-1)
continue;
if(roman2 == X && i!= 0){
temp += 90;
continue;
}
else {
temp += 100;
}
break;
case 'D' :
if(roman2 == C && i!= 0){
temp += 400;
continue;
}
else {
temp += 500;
}
break;
case 'M':
if(roman2 == C && i!= 0){
temp += 900;
continue;
}
else {
temp += 1000;
}
break;
}
}
temp2 = temp;
}
void showDecimal() {
cout << "Here is your roman numeral in decimal format:";
cout << temp2 << " \n \n \n";
}
};
romanType::romanType () {
numeral = "";
}
int main() {
string k = acceptRN();
int m = 0;
char l= ' ';
romanType type;
type.getRnumeral(k);
type.decimal(k, m, l);
type.showDecimal();
return 0;
}
string acceptRN(){
string num = "";
cout << "Please type in your roman numeral:" ;
cin >> num;
return num;
}
When I done the stuff from my comment and tweaked your code a bit I got this:
//---------------------------------------------------------------------------
int roman_ix[256]={-1};
const int roman_val[]={ 1 , 5 ,10 ,50 ,100,500,1000,0};
const char roman_chr[]={'I','V','X','L','C','D', 'M',0};
//---------------------------------------------------------------------------
int roman2int(char *s)
{
int i,x=0,v=0,v0;
// init table (just once)
if (roman_ix[0]<0)
{
for (i=0;i<256;i++) roman_ix[i]=0;
for (i=0;roman_chr[i];i++) roman_ix[roman_chr[i]]=i;
}
// find end of string
for (i=0;s[i];i++);
// proccess string in reverse
for (i--;i>=0;i--)
{
v0=v; // remember last digit
v=roman_val[roman_ix[s[i]]]; // new digit
if (!v) break; // stop on non supported character
if (v0>v) x-=v; else x+=v; // add or sub
}
return x;
}
//---------------------------------------------------------------------------
I tested on these:
1776 1776 MDCCLXXVI
1954 1954 MCMLIV
1990 1990 MCMXC
2014 2014 MMXIV
300 300 CCC
first number is converted from string, second is what it should be and last is the roman string.
If 256 entry table is too big you can shrink it to range A-Z which is significantly smaller but that require one more substraction in the code. It can be also hardcoded to get rid of the initialization:
//---------------------------------------------------------------------------
int roman2int(char *s)
{
// init
int i,x=0,v=0,v0; // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
const int val['Z'-'A'+1]={ 0, 0, 100, 500, 0, 0, 0, 0, 1, 0, 0, 50, 1000, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 0, 0 };
// find end of string
for (i=0;s[i];i++);
// process string in reverse
for (i--;i>=0;i--)
{
if ((s[i]<'A')||(s[i]>'Z')) break; // stop on non supported character
v0=v; v=val[s[i]-'A'];
if (v0>v) x-=v; else x+=v;
}
return x;
}
//---------------------------------------------------------------------------
As I got rid of your temp and roman1,roman2 and the switch if/else conditions and the code worked from the first compilation ... I am assuming that you are doing something fishy with them (got lost in the if/else combinations missing some edge case).

more than two numbers Hexadecimal addtion

My code just can add two Hedecimal numbers, but we should add more than two, the input just like this FFFFFFFFFFFFF+1+2+3+4 maybe more addtion. We can use operator overloading.
That's my code.
#include <iostream>
#include <string>
#include<cstddef>
#include<cstring>
using namespace std;
int changeint(char a)
{
switch(a)
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
case 'A': return 10;
case 'B': return 11;
case 'C': return 12;
case 'D': return 13;
case 'E': return 14;
case 'F': return 15;
}
}
char changechar(int a)
{
switch(a)
{
case 0: return '0';
case 1: return '1';
case 2: return '2';
case 3: return '3';
case 4: return '4';
case 5: return '5';
case 6: return '6';
case 7: return '7';
case 8: return '8';
case 9: return '9';
case 10:return 'A';
case 11:return 'B';
case 12:return 'C';
case 13:return 'D';
case 14:return 'E';
case 15:return 'F';
}
}
int main()
{
string input,input_one,input_two;
int count_one,count_two;
cin>>input;
count_one=input.find('+',0);
count_two=input.length();
input_one=input.substr(0,count_one);
input_two=input.substr(count_one+1,count_two-count_one-1);
char a[1000];
char b[1000];
char c[1001];
a[1000]=0;
strcpy(a,input_one.c_str());
b[1000]=0;
strcpy(b,input_two.c_str());
int A[1000],B[1000],C[1001],i,lena=0,lenb=0,lenc=1000;
for(i=0;i<1001;i++)
C[i]=0;
for(i=0;i<1000;i++)
{
A[i]=0;
B[i]=0;
}
while(a[lena]!=0) lena++;
while(b[lenb]!=0) lenb++;
for(i=0;i<lena;i++)
A[lena-i-1]=changeint(a[i]);
for(i=0;i<lenb;i++)
B[lenb-i-1]=changeint(b[i]);
for(i=0;i<1000;i++)
{
C[i]=C[i]+A[i]+B[i];
if(C[i]>15)
{
C[i]=C[i]-16;
C[i+1]++;
}
}
for(i=999;i>=0;i--)
{
if(C[i]==0) lenc--;
else break;
}
if(lenc==0)
lenc=1;
for(i=0;i<lenc;i++)
c[i]=changechar(C[lenc-i-1]);
for(i=0;i<lenc;i++)
cout<<c[i];
return 0;
}
Thanks for your help.
This is a very convoluted program to solve a pretty trivial problem. Hint: decimal and hexadecimal is a way to represent a number, arithmetic operations will still be the same. Since you marked this question as C++, a standard library could be used. This is simple example how addition of five numbers could be achieved:
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> vNumbers;
for(int i=0; i<5; ++i)
{
int nNum = 0;
std::cin >>std::hex >> nNum;
vNumbers.push_back(nNum);
}
int nSum = std::accumulate(vNumbers.begin(), vNumbers.end(), 0);
std::cout<<std::hex<<nSum<<std::endl;
return 0;
}
Firstly, you need to compose and tokenize your strings using the '+' symbol.
Then you need to convert them using inbuilt handling libraries - trying to work on this data as strings will only cause you pain!
Thirdly, I'd recommend you start again as this code looks pretty bad, sorry :0
Solve your problem conceptually on paper (considering the use of native handling of parsed hex types) then solve it in the IDE.
Good Luck!
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Hedadd
{
private:
string input_string;
public:
void set_the_neibu(string input_the_string);
friend Hedadd operator+(const Hedadd& string_one,const Hedadd& string_two);
void output();
};
void input(string input_string,char zheng,Hedadd first_string[100],Hedadd add);
int changeint(string a)
{
for (int i=0;i<100;i++)
{
if(a[i]=='0')
a[i]='0';
if(a[i]=='1')
a[i]='1';
if(a[i]=='2')
a[i]='2';
if(a[i]=='3')
a[i]='3';
if(a[i]=='4')
a[i]='4';
if(a[i]=='5')
a[i]='5';
if(a[i]=='6')
a[i]='6';
if(a[i]=='7')
a[i]='7';
if(a[i]=='8')
a[i]='8';
if(a[i]=='9')
a[i]='9';
if(a[i]=='A')
a[i]='10';
if(a[i]=='B')
a[i]='11';
if(a[i]=='C')
a[i]='12';
if(a[i]=='D')
a[i]='13';
if(a[i]=='E')
a[i]='14';
if(a[i]=='F')
a[i]='15';
return a[i];
}
}
string changestring(int a[100])
{
for(int i=0;i<100;i++)
{
if(a[i]==0)
a[i]=0;
if(a[i]==1)
a[i]=1;
if(a[i]==2)
a[i]=2;
if(a[i]==3)
a[i]=3;
if(a[i]==4)
a[i]=4;
if(a[i]==5)
a[i]=5;
if(a[i]==6)
a[i]=6;
if(a[i]==7)
a[i]=7;
if(a[i]==8)
a[i]=8;
if(a[i]==9)
a[i]=9;
if(a[i]==10)
a[i]='A';
if(a[i]==11)
a[i]='B';
if(a[i]==12)
a[i]='C';
if(a[i]==13)
a[i]='D';
if(a[i]==14)
a[i]='E';
if(a[i]==15)
a[i]='F';
}
}
string xiangjia(string one,string two)
{
int one_length,two_length,longer,cha,smaller,sum[1000];
string adding_result;
one_length=one.length();
two_length=two.length();
if(one_length<=two_length)
{
longer=two_length;
smaller=one_length;
cha=two_length-one_length;
for(int i=0;i<smaller;i++)
{
one[i+cha]=one[i];
}
for(int m=0;m<cha;m++)
{
one[m]='0';
}
}
else
{
longer=one_length;
smaller=two_length;
cha=one_length-two_length;
for(int i=0;i<smaller;i++)
{
two[i+cha]=two[i];
}
for(int m=0;m<cha;m++)
{
two[m]='0';
}
}
changeint(one);
changeint(two);
for(int i=longer;i>0;i--)
{
sum[i]=one[i]+two[i];
if(sum[i]>='16')
sum[i]=sum[i]-16;
sum[i-1]=sum[i-1]+1;
}
for(int i=longer;i>0;i--)
{
adding_result=changestring(sum);
}
return (adding_result);
}
int main()
{
string input_string;
char zheng;
Hedadd first_string[100],add;
zheng='+';
input(input_string,zheng,first_string,add);
add.output();
return 0;
}
void Hedadd ::set_the_neibu(string input_the_string)
{
input_string=input_the_string;
}
void input(string input_string,char zheng,Hedadd first_string[100],Hedadd add)
{
for(int i=0;i<100;i++)
{
if(i==0)
{
cin>>input_string;
first_string[i].set_the_neibu(input_string);
add=first_string[i];
}
if(i!=0)
{
cin>>zheng>>input_string;
first_string[i].set_the_neibu(input_string);
add=add+first_string[i];
}
}
}
Hedadd operator+(const Hedadd& string_one,const Hedadd& string_two)
{
Hedadd string_together;
string_together.input_string=xiangjia(string_one.input_string,string_two.input_string);
return(string_together);
}
void Hedadd::output()
{
cout<<input_string;
}
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Hedadd
{
private:
string input_string;
public:
void set_the_neibu(string input_the_string);
friend Hedadd operator+(const Hedadd& string_one, const Hedadd& string_two);
void output();
};
Hedadd input(string input_string, char zheng, Hedadd first_string, Hedadd add);
void changeint(char a[100],int b[100])
{
for (int i = 0; i<100; i++)
{
if (a[i] <= '9'&&a[i]>='0')
b[i] = a[i] - '0';
else
b[i] = a[i] - 'A' + 10;
}
}
string changestring(int a[100])
{
char b[101];
for (int i = 0; i<100; i++)
{
if (a[i] <= 9&&a[i] >= 0)
b[i] = a[i] + '0';
else
b[i] = a[i] + 'A' - 10;
}
b[100] = '\0';
return string(b);
}
string xiangjia(string one, string two)
{
int one_length, two_length, longer, cha, smaller, sum[100];
char c_one[100];
char c_two[100];
int int_one[100];
int int_two[100];
string adding_result;
one_length = one.length();
two_length = two.length();
longer = one_length > two_length ? one_length : two_length;
for (int i = 0; i < 100; i++)
{
c_one[i] = '0';
c_two[i] = '0';
sum[i] = 0;
}
for (int i = 1; i <= one_length; i++)
{
c_one[100 - i] = one.c_str()[one_length - i];
}
for (int i = 1; i <= two_length; i++)
{
c_two[100 - i] = two.c_str()[two_length - i];
}
changeint(c_one,int_one);
changeint(c_two,int_two);
for (int i = 1; i<=longer; i++)
{
sum[100 - i] += int_one[100 - i] +int_two[100 - i];
if (sum[100 - i] >= 16)
{
sum[100 - i] = sum[100 - i] - 16;
sum[100 - i - 1] = sum[100 - i - 1] + 1;
}
}
adding_result = changestring(sum);
int count = 0;
for (count = 0; count < 100; count++)
{
if (sum[count]!=0)
{
break;
}
}
return (adding_result.substr(count,adding_result.length() - count));
}
int main()
{
string input_string;
char zheng;
Hedadd first_string, add;
zheng = '+';
add = input(input_string, zheng, first_string, add);
add.output();
return 0;
}
void Hedadd::set_the_neibu(string input_the_string)
{
input_string = input_the_string;
}
Hedadd input(string input_string, char zheng, Hedadd first_string, Hedadd add)
{
string temp = "";
cin >> temp;
add.set_the_neibu("0");
int offset = temp.find_first_of('+');
while (offset != std::string::npos)
{
first_string.set_the_neibu(temp.substr(0,offset));
add = add + first_string;
temp = temp.substr(offset+1, temp.length() - offset-1);
offset = temp.find_first_of('+');
}
first_string.set_the_neibu(temp.substr(0, offset));
add = add + first_string;
return add;
}
Hedadd operator+(const Hedadd& string_one, const Hedadd& string_two)
{
Hedadd string_together;
string_together.input_string = xiangjia(string_one.input_string, string_two.input_string);
return(string_together);
}
void Hedadd::output()
{
cout << input_string;
}
enter code here