I have a terrible program in C++ when I try to assign a enum value.
The error exists when I try to assign Wall or Free etc to sokoban.board[j,i].
bool loadLevel(ifstream &stream, tSokoban &sokoban, int level) {
bool ok = false;
string levelStr, levelFile = " ", prove;
int j = 0;
levelStr = "Level " + to_string(level);
while (levelFile != levelStr && EOF) {
getline(stream, levelFile);
}
if (levelFile == levelStr) {
ok = true;
getline(stream, prove);
sokoban.ncol = prove.size();
while (prove != "Level " + to_string(level + 1)) {
for (int i = 0; i < prove.size(); i++) {
switch (prove[i]) {
case '#':
sokoban.board[j, i] = Wall;
break;
case ' ':
sokoban.board[j, i] = Free;
break;
case '$':
sokoban.board[j, i] = Box;
break;
case '.':
sokoban.board[j, i] = GoalFree;
break;
case '#':
sokoban.board[j, i] = Player;
break;
}
}
getline(stream, prove);
j++;
}
sokoban.nrows = j - 1;
}
return ok;
}
It's hard to know where is the problem because these are the declarations:
typedef tTile tBoard[MAX][MAX];
typedef struct {
tBoard board;
int nrows;
int ncol;
int rowPlayer;
int colPlayer;
int numBoxes;
int goalBoxes;
}tSokoban;
typedef struct {
tSokoban sokoban;
int numMoves;
string nFileName;
int level;
}tGame;
And if I write in the code: sokoban.board[j,i] this error dissapeared, could anyone tell me why this error happen?
Sorry about this mess but I don't know how to use properly this task.
The data member
tBoard board;
has the array type tTile[MAX][MAX] due to the typedef
typedef tTile tBoard[MAX][MAX];
So to access an element of the two-dimensional array you should use the postfix expression like
sokoban.board[j][i] = Wall;
where the expression sokoban.board[j][i] yields an lvalue of type tTile.
As for this expression
sokoban.board[j, i] = Wall;
then there is used the comma operator in the square braces. In fact it is equivalent to
sokoban.board[i] = Wall;
The expression sokoban.board[i] has the one-dimensional array type tTile[MAX] (see the typedef above) and is not a modifiable lvalue.
Related
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++.
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).
I am required to develop a program to solve linear equations. The programs
reads first an integer n which is the number of equations.
Then the program reads n lines containing the equations.
For example, the input to the program is like:
3
2x1+3x2+4x3=16
1x1+2x2+1x3=8
3x1+1x2+2x3=13
Any operation should first convert every equation to
the proper form. The equation proper should have the following properties
Variables are ordered alphabetically from left to right:
3x2+2x1+4x3=16
Should be
2x1+3x2+4x3=16
Any variable should appear only once:
4x1+3x2-2x1+4x3=16
Should be
2x1+3x2+4x3=16
Only one constant term should appear in the equation and it should be
on the right hand side:
2x1+3x2+5+4x3-11=10
Should be
2x1+3x2+4x3=16
Coefficient when equals to one or -1 the digit 1 is optional:
1x1+3x2-1x3=10
Can be input as be
x1+3x2-x3=10
What I have done so far is as follows:
#include<iostream>
#include<string>
#include<sstream>
#include<cstdlib>
using namespace std;
int main() {
int n;
cin >> n;
string eqn[100];
//get eq from user
for (int i = 0; i < n; i++) {
cin >> eqn[i];
}
size_t s = 0;
size_t y = 0;
for (int i = 0; i < n; i++) {
for (int x = 1; x <= ((eqn[i].length() - ((eqn[i].length() - 3) / 4)) / 3); x++)
{
int counter = 0;
ostringstream ss;
ss << x;
string j = ss.str();
for (int t = 0; t < eqn[i].length(); t++) {
y = eqn[t].find("x" + j, y + 1);
if (y < eqn[i].length()) { counter++; }
}
for (int o = 1; o <= counter; o++) {
s = eqn[i].find("x" + j, s + 1);
string x1 = eqn[i].substr(s - 1, 3);
string x2 = x2 + x1;
cout << x1;
}
}
cout << endl;
}
int k; cin >> k;
return 0;
}
but things became over complicated, and I am not sure if that is the right approach..
Is there a better way to operate on a string equation other than find(), substr()?
How should I approach the problem?
I started with a Syntax Diagram to define (I wouldn't call it) a language:
Then I translated this into a hand-written parser.
parse-equation.cc:
#include <iostream>
#include <algorithm>
int parseDigit(const char *&la)
{
switch (*la) {
case '0': ++la; return 0;
case '1': ++la; return 1;
case '2': ++la; return 2;
case '3': ++la; return 3;
case '4': ++la; return 4;
case '5': ++la; return 5;
case '6': ++la; return 6;
case '7': ++la; return 7;
case '8': ++la; return 8;
case '9': ++la; return 9;
default: return -1; // ERROR!
}
}
int parseNumber(const char *&la)
{
int value = parseDigit(la);
if (value < 0) return -1; // ERROR!
for (;;) {
const int digit = parseDigit(la);
if (digit < 0) return value;
value *= 10; value += digit;
}
}
struct Term {
int coeff; // -1 ... missing
int expon; // -1 ... missing -> ERROR
Term(int coeff = -1, int expon = 0): coeff(coeff), expon(expon) { }
};
Term parseTerm(const char *&la)
{
Term term;
term.coeff = parseNumber(la);
if (*la == 'x') {
++la;
term.expon = parseDigit(la);
if (term.coeff < 0) term.coeff = 1; // tolerate missing coeff. for x
}
return term;
}
struct Expression {
bool error;
int coeffs[10];
Expression(bool error = false): error(error)
{
std::fill(std::begin(coeffs), std::end(coeffs), 0);
}
};
Expression parseExpression(const char *&la)
{
Expression expr;
int sign = +1;
do {
const Term term = parseTerm(la);
if (term.expon < 0) return Expression(true); // ERROR!
expr.coeffs[term.expon] += sign * term.coeff;
switch (*la) {
case '+': sign = +1; ++la; break;
case '-': sign = -1; ++la; break;
case '=': break;
default: return Expression(true); // ERROR!
}
} while (*la != '=');
++la;
// parse right hand side
const int result = parseNumber(la);
if (result < 0) return Expression(true); // ERROR!
expr.coeffs[0] -= result;
// check for extra chars
switch (*la) {
case '\n': ++la;
case '\0': break;
default: return Expression(true); // ERROR!
}
return expr;
}
std::ostream& operator<<(std::ostream &out, const Expression &expr)
{
if (expr.error) out << "ERROR!";
else {
bool empty = true;
for (size_t i = 9; i; --i) {
const int coeff = expr.coeffs[i];
if (coeff) out << coeff << 'x' << i << std::showpos, empty = false;
}
if (empty) out << 0;
out << std::noshowpos << '=' << -expr.coeffs[0];
}
return out;
}
int main()
{
const char *samples[] = {
"2x1+3x2+4x3=16",
"1x1+2x2+1x3=8",
"3x1+1x2+2x3=13",
"2x1+3x2+5+4x3-11=10",
"x1+3x2-x3=10"
};
enum { nSamples = sizeof samples / sizeof *samples };
for (size_t i = 0; i < nSamples; ++i) {
std::cout << "Parse '" << samples[i] << "'\n";
const char *la = samples[i];
std::cout << "Got " << parseExpression(la) << std::endl;
}
return 0;
}
Compiled with g++ and tested in cygwin:
$ g++ -std=c++11 -o parse-equation parse-equation.cc
$ ./parse-equation
Parse '2x1+3x2+4x3=16'
Got 4x3+3x2+2x1=16
Parse '1x1+2x2+1x3=8'
Got 1x3+2x2+1x1=8
Parse '3x1+1x2+2x3=13'
Got 2x3+1x2+3x1=13
Parse '2x1+3x2+5+4x3-11=10'
Got 4x3+3x2+2x1=16
Parse 'x1+3x2-x3=10'
Got -1x3+3x2+1x1=10
$
Life Demo on Coliru
Note:
Instead of parseDigit() and parseNumber(), std::strtol() could be used. This would reduce the code significantly.
I used const char* for the "read head" la (... abbr. for "look ahead"). The pure C++ way might have been a std::stringstream or a std::string::iterator but, may be, I'm not used enough to these new fancy things. For me, the const char* was the most intuitive way...
The result on right hand side is simply subtracted from the coefficient for x0. So, either the right hand side is 0, or the negative coefficient for x0 becomes right hand side. For my pretty-printing operator<<(), I chose the latter option.
The error handling is rather poor and could be enhanced with more detailed infos about the reason of failed parsing. I left this out to not to "blow" the code even more.
The parser could be enhanced easily to skip white space at any appropriate place. This would improve the convenience.
In the current state, the result on right hand side might not be a negative number. I leave this extension as exercise.
I'm new to C++ and I'm trying to figure out why I get two "*" symbols in my game board when I'm moving around. The game is supposed to be about avoiding the troll (#). But I am getting duplicate # and * symbols, and I can't figure out why. It seems that the problem is either in one of the for loops or in the posX or posY variables, which I found out by commenting out segments of the code:
#include <iostream>
#include <string>
using namespace std;
void ClearScreen()
{
cout << string(100, '\n');
}
main()
{
int size_arrx = 10;
int size_arry = 20;
int posX = 0;
int posY = 0;
int trollX = size_arrx - 1;
int trollY = size_arry - 1;
char a[size_arry][size_arrx];
bool Alive = true;
char player = '*';
char troll = '#';
while (Alive == true) {
ClearScreen();
for (int i = 0; i<size_arrx; i++)
{
for (int j = 0; j<size_arry; j++)
{
a[i][j] = 'x';
}
}
for (int i = 0; i<size_arrx; i++)
{
for (int j = 0; j<size_arry; j++)
{
a[posX][posY] = player;
a[trollX][trollY] = troll;
cout << a[i][j];
if (posX< 0) {
a[posX = 0][posY] = player;
cout << a[i][j];
}
else if (posY< 0) {
a[posX][posY = 0] = player;
cout << a[i][j];
}
else if (posY > size_arry - 1) {
a[posX][posY = size_arry - 1] = player;
cout << a[i][j];
}
else if (posX > size_arrx - 1) {
a[posX = size_arrx - 1][posY] = player;
cout << a[i][j];
}
}
cout << endl;
}
char dir;
cin >> dir;
if (dir == 'w') {
trollX++;
posX--;
}
if (dir == 's') {
trollX--;
posX++;
}
if (dir == 'd') {
trollY--;
posY++;
}
if (dir == 'a') {
trollY++;
posY--;
}
}
if ((trollX == posX) && (trollY == posY)) {
Alive == false;
}
}
The result looks like this. I only want one *. The * can move perfectly fine, but a duplicate * follows the original * but 11 X's away.
xxxxxxxxxx*xxxxxxxxx <---- This is a duplicate *
*xxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx#
xxxxxxxxx#xxxxxxxxxx <---- This is a duplicate #
Thanks in advance if you can help me
for (int i=0;i<size_arrx;i++){
for (int j=0;j<size_arry;j++){
a[i][j]='x';
}
}
a[posX][posY]=player;
a[trollX][trollY]=troll;
for (int i=0;i<size_arrx;i++){
for (int j=0;j<size_arry;j++){
cout << a[i][j];
Using this code gave the same error. I'm interpreting this as a[i][j]='x' populates all positions of a[][] with X's. a[posX][posY]=player; overwrites the position of the player with an * (could be x 2 y 5 for example) and then the board gets printed by cout << a[i][j];. I don't understand how a duplicate symbol gets thrown in there.
Let's simplify your program.
Initialize the board outside of the while loop.
There should be no reason to keep initializing it:
for (unsigned int row = 0; row < size_arry; ++row)
{
std::fill(&a[row][0], &a[row][size_arrx], 'x'); // Fill a row.
}
Printing the board should be simple:
for (unsigned int row = 0; row < size_arry; ++row)
{
for (unsigned int column = 0; column < size_arrx; ++column)
{
cout << a[row][column];
}
cout << '\n';
}
Now the character logic.
Every character has a position, row and column, of where it is. To ease restoration, every character should have a previous position also.
struct Position
{
unsigned int row;
unsigned int column;
};
Sorry about that code, the fingers and keyboard are not cooperating.
To move a character to a valid new position, you have to restore the previous position:
unsigned int player_now_x;
unsigned int player_now_y;
unsigned int player_prev_x;
unsigned int player_prev_y;
//...
a[player_prev_y][player_prev_x] = 'x';
a[player_now_y][player_now_y] = player;
For processing single letter commands, a switch statement may be more readable:
// Update previous position.
player_prev_x = player_now_x;
player_prev_y = player_now_y;
switch (dir)
{
case 'd':
if (player_now_y < size_arry)
{
++player_now_y;
}
break;
case 's':
if (player_now_x < size_arrx)
{
++player_now_x;
}
break;
// ...
}
Simplifications.
You can print the board with one cout if you add an extra column. The ending column of each row (except the last) will have a line ending character, '\n'. The last column of the last row will have a termination character, '\0'.
struct Board
{
void set_player(const Position& pos, char player_token)
{
a[pos.x][pos.y] = player_token;
}
void move_player(const Position& new_position,
const Position& previous_position,
char player_token)
{
set_player(previous_position, 'x');
set_player(new_position, player_token);
}
void print()
{
std::cout << &a[0][0] << "\n";
}
Board()
{
for (unsigned int y = 0; y < size_arry; ++y)
{
std::fill(&a[y][0], &a[y][size_arrx], 'x');
a[y][size_arrx - 1] = '\n';
}
a[size_arry - 1][size_arrx - 1] = '\0';
}
};
//...
Board b;
Position player_now;
Position player_prev;
const char player_token = '*';
//...
switch (dir)
{
case 'd':
if (player_now.y < size_arry)
{
++player_now.y;
}
//...
}
b.move_player(player_now, player_previous, player_token);
Sorry again, for the above code fragment, it's the fingers typing out what they want.
I have some code pasted here that keeps giving me the error in the title whenever more than one number is given as input. I cannot find one place where inputValue is being improperly accessed, but I could use another (few) sets of eyes. Thanks for any help ahead of time!
// descriptions of declared functions listed with implementation
int ProcessInput(const int fromBase, const int toBase, char inputValue[],
const int length);
void ConvertToBase(int decimal, const int inBase, char outPut[]);
double Exponent(const int number, const int exponent);
int main(int argsc, char** argsv)
{
int fromBase(0), toBase(0);
// set bases and initialize vector for storing output until end of input
fromBase = atoi(argsv[1]);
toBase = atoi(argsv[2]);
vector <char *> outPutValues;
int count(0);
while (!cin.eof())
{
// array to hold input value
char inputValue[8] = {' '};
// receive input from keyboard and convert input to decimal and new base
while (cin >> inputValue)
{
int length(strlen(inputValue));
// using dynamic arrays in vector allows for multiple input
// with no output until all input received
outPutValues.push_back(new char[8]);
int decimalValue = ProcessInput(fromBase, toBase, inputValue,
length);
// if the new base is decimal, simply output decimalValue;
// else process the new base and store in an output array;
ConvertToBase(decimalValue, toBase, outPutValues[count]);
count++;
}
for (int c = 0; c < outPutValues.size(); c++)
{
int k(0);
// display only set values of the output array
while ((outPutValues[c][k] == '\0') || (outPutValues[c][k] == '0'))
k++;
while (k < 8)
{
cout << outPutValues[c][k];
k++;
}
cout << endl;
}
}
// free up dynamic arrays
for (int d = 0; d < outPutValues.size(); d++)
delete outPutValues[d];
return 0;
} // end main
// ProcessInput receives the input array and translates the char values
// into a decimal value to be returned to calling function
int ProcessInput(const int fromBase, const int toBase, char inputValue[],
const int length)
{
int exponent(0), decimalValue(0);
for (int j = 0; j < length; j++)
{
exponent = (length - j - 1);
// convert inputValue from char to int to be processed into decimal;
// negative signs are ignored
switch (inputValue[j])
{
case 'a':
case 'A': decimalValue += (10 * Exponent(fromBase, exponent)); break;
case 'b':
case 'B': decimalValue += (11 * Exponent(fromBase, exponent)); break;
case 'c':
case 'C': decimalValue += (12 * Exponent(fromBase, exponent)); break;
case 'd':
case 'D': decimalValue += (13 * Exponent(fromBase, exponent)); break;
case 'e':
case 'E': decimalValue += (14 * Exponent(fromBase, exponent)); break;
case 'f':
case 'F': decimalValue += (15 * Exponent(fromBase, exponent)); break;
case '-': cout << "Negative Number Received. Converted to unsigned int.\n"; break;
default: decimalValue += ((inputValue[j] - '0') * Exponent(fromBase, exponent)); break;
}
}
return decimalValue;
} // end ProcessInput
// ConvertToBase converts the decimal form of a number into
// a new base by dividing the decimal until 0 and
// storing the remainders in the output array
void ConvertToBase(int decimal, const int inBase, char outPut[])
{
int remainder(0);
// char variable used to convert int back into char
// for output
char intToChar('0');
for (int i = 7; i >= 0; i--)
{
remainder = decimal % inBase;
decimal /= inBase;
// account for hex and if remainder is an int,
// store as char in output array using char intToChar
switch (remainder)
{
case 10: outPut[i] = 'A'; break;
case 11: outPut[i] = 'B'; break;
case 12: outPut[i] = 'C'; break;
case 13: outPut[i] = 'D'; break;
case 14: outPut[i] = 'E'; break;
case 15: outPut[i] = 'F'; break;
default: for (int j = 0; j < remainder; j++) {intToChar++;}
outPut[i] = intToChar;
intToChar = '0';
break;
}
}
} // end ConvertToBase
// converts input to decimal form by multiplying
// each number place by its base and exponent
double Exponent(const int number, const int exponent)
{
double value(1);
for (int i = 1; i <= exponent; i++)
value *= number;
return value;
} // end Exponent
#JeffA. you are missing the trailing \0. – erikced
Yes sir, just saw this right before I saw your answer. I need that extra element for the null terminator. Thanks! I know this project is messy and more C than C++, but the template is what it is. Thanks for all the help guys and gals!