need help on debugging my c++ programming (text ascii manupulation) - c++

I recently made a C++ program which encrypts texts based-on the vigenere cipher technique.
The encryption part works fine I think, but the decryption function doesn't seem to output the correct answer in some cases. I was hoping if anyone could have a look at code and tell me what's wrong with it.
CMD dialog:
Enter the key for encrytion:
magic
Enter message No. 1:
I love C programming
Message encrypted:
u rwxq i rdomzcymovi
Decrypted:
i love c pXogramming
Somehow it outputted "X" instead of "r" in this case.............
Here are the codes:
Secret.h:
#ifndef CPP_TUTORIALS_SECRET_H
#define CPP_TUTORIALS_SECRET_H
#include <iostream>
using namespace std;
class Secret {
private:
string message;
string key;
bool toEncrypt;
bool toDecrypt;
public:
bool isToDecrypt() const {
return toDecrypt;
}
Secret(const string &message = "", const string &key = "", bool toEncrypt = false);
~Secret();
void setToDecrypt(bool toDecrypt);
void encrypt();
void decrypt();
void display();
};
#endif //CPP_TUTORIALS_SECRET_H
Secret.cpp
#include "Secret.h"
Secret::Secret(const string &message, const string &key, bool toEncrypt) {
Secret::message = message;
Secret::key = key;
Secret::toEncrypt = toEncrypt;
}
Secret::~Secret(){
}
void Secret::setToDecrypt(bool toDecrypt) {
Secret::toDecrypt = toDecrypt;
}
void Secret::display() {
cout << message << endl;
}
void Secret::encrypt() {
if(toEncrypt) {
int keyAscii[key.length()];
int count = 0;
for(unsigned int i = 0; i < key.length(); i++) {
keyAscii[i] = key.at(i);
}
for(unsigned int i = 0; i < message.length(); i++) {
if (message.at(i) > 64 && message.at(i) < 91) {
message.at(i) = (char)((message.at(i) - 65 + (keyAscii[count] - 97)) % 26 + 97);
}
else if (message.at(i) > 96 && message.at(i) < 123) {
message.at(i) = (char)((message.at(i) - 97 + (keyAscii[count] - 97)) % 26 + 97);
}
else{
message.at(i) = message.at(i);
}
count++;
if(count == key.length()) {
count = 0;
}
}
}
}
void Secret::decrypt() {
if(toDecrypt) {
int keyAscii[key.length()];
int count = 0;
for(unsigned int i = 0; i < key.length(); i++) {
keyAscii[i] = key.at(i);
}
for(unsigned int i = 0; i < message.length(); i++) {
if (message.at(i) > 96 && message.at(i) < 123) {
message.at(i) = (char)((message.at(i) - 97) % 26 - (keyAscii[count] - 97) + 97);
}
else {
message.at(i) = message.at(i);
}
count++;
if (count == key.length()) {
count = 0;
}
}
}
}
main.cpp
#include <limits>
#include "Secret.h"
void calcMsgAmount(int &pArraySize);
void inputKey(string &key);
void encryptMsg(Secret &secret, string &msg, const string &key, bool toEncrypt, int index);
int main() {
int arraySize;
string key;
string msg;
calcMsgAmount(arraySize);
inputKey(key);
Secret secrets[arraySize];
for(int i = 0; i < arraySize; i++){
encryptMsg(secrets[i], msg, key, true, i);
}
cout << endl << "Message encrypted: " << endl;
for(Secret i: secrets){
i.display();
i.setToDecrypt(true);
if(i.isToDecrypt()){
i.decrypt();
cout << endl << "Decrypted: " << endl;
i.display();
}
cout << endl << endl;
}
return 0;
}
void calcMsgAmount(int &pArraySize) {
cout << "Enter the amount of messages you want to input: " << endl;
while(!(cin >> pArraySize)){
cout << endl << "There's something really wrong with your input, please enter again." << endl;
cout << "Enter the amount of messages you want to input: " << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
void inputKey(string &key){
cout << "Enter the key for encrytion: " << endl;
cin.ignore();
getline(cin, key);
}
void encryptMsg(Secret &secret, string &msg, const string &key, bool toEncrypt, int index){
cout << "Enter message No. " << index + 1 << ": " << endl;
getline(cin, msg);
secret = Secret(msg, key, toEncrypt);
secret.encrypt();
}
Many thanks

accroding to wikipedia the decrypt routine of Vigenere Cipher is
(C - K) mod 26
what you wrote in Secret::decrypt() is
message.at(i) = (char)((message.at(i) - 97) % 26 - (keyAscii[count] - 97) + 97);
which is C % 26 - K.
I changed the line to
message.at(i) = (char)((26 + (message.at(i) - 97) - (keyAscii[count] - 97)) % 26 + 97);
it seems to be correct. I haven't really understood why the first 26 is necessary, but without it the code doesn't work (something with % and negative numbers)
P.S. as for debugging part, you might have noticed that whong letters appear as wrong capital letters which have smaller ascii code, so you decrypt routine has negative numbers in it. After which you check your code against Wikipedia :)

The problem comes in the decrypt from two problems:
the first is that the calculation should be symetric from the the encryp, i.e. the modulo 26 for message - key (as already pointed out by effenok)
the second is that in the decrypt you can at char level, message-key can be negative, which might not give you the expected results modulo 26 (for example -2 % 26 is -2 so that you'll be out of the alphabetic range that you expect). The easy trick is to add 26 before doing the modulo, which makes sure it's done on a positive number.
Here slightly more compact functions, making the difference between uppercase and lowercase :
void Secret::encrypt() {
if(toEncrypt) {
for(unsigned int i = 0; i < message.length(); i++) {
if(isalpha(message[i])){
char start = isupper(message[i]) ? 'A' : 'a';
message[i] = (message[i] - start + (tolower(key[i%key.length()]) - 'a') + 26) % 26 + start;
}
}
}
}
void Secret::decrypt() {
if(toDecrypt) {
for(unsigned int i = 0; i < message.length(); i++) {
if (isalpha(message[i]) ){
char start = isupper(message[i]) ? 'A':'a';
message[i] = (message[i] - start - (tolower(key[i%key.length()]) - 'a') + 26) % 26 + start;
}
}
}
}

Related

I keeping the error "'std::logic_error' what(): basic_string::_M_construct null not valid" when i am trying to execute my code

I am making a cypher code and when I am trying to execute it I get the "std::logic_error' what(): basic_string::_M_construct null not valid". what is wrong with the code.
#include <iostream>
using namespace std;
string cipher(int key,string text);
string decipher(int key,string text);
int main(int argc, char** argv) {
string type;
string text;
string dtext;
char* key1;
int key;
string s = argv[1];
if (argc != 2) {
cout << "Usage ./ceaser key" << endl;
return 1;
}
else {
for (int k = 0;k < s.length(); k++) {
if (isalpha(argv[1][k]))
{
cout << "Usage: ./caesar key" << endl;
return 1;
}
else
{
continue;
}
}
}
cout << "Type c for cipher and d for decipher: ";
cin >> type;
cout << "text: ";
getline(cin, text);
key1 = argv[1];
key = atoi(key1);
if (type == "c") {
cipher(key,text);
}
else {
decipher(key,text);
}
cout << endl;
}
string cipher(int key,string text) {
for (int i = 0; i < text.length(); i++) {
if (islower(text[i])) {
char m = (((text[i] + key) - 97) % 26) + 97;
cout << m;
}
else if(isupper(text[i])){
char a = (((text[i] + key) - 65) % 26) + 65;
cout << a;
}
else {
cout << text[i];
}
}
return 0;
}
string decipher(int key,string text) {
for (int i = 0; i < text.length(); i++) {
if (islower(text[i])) {
char m = (((text[i] - key) - 97) % 26) + 97;
cout << m;
}
else if(isupper(text[i])){
char a = (((text[i] - key) - 65) % 26) + 65;
cout << a;
}
else {
cout << text[i];
}
}
return 0;
}
How can I fix this, it worked fine when I only made it a cypher but not decipher. but when I try to decipher it stopped working.
string cipher(int key,string text) {
...
return 0;
}
a return statement applies the appropriate constructor of the return type, if the returned value is not of the correct type. In this case std::string::string(const char*) is used and the null pointer is passed causing the issue. You need to return the result of the encryption here instead of printing the result to stdout. (Proceed accordingly in decypher.)
In this case contrary to my comment you may actually pass the value by copy to be able to modify the string and return it:
...
if (islower(text[i])) {
//char m = (((text[i] + key) - 97) % 26) + 97;
//cout << m;
text[i] = (((text[i] + key) - 97) % 26) + 97;
}
...
return text;

C++ full subtractor using hexadecimals

I have input such as:
10000000000000-1=
and
AAAAABBBBBCCCCCDDDDDEEEEEFFFFF-ABCDEF0123456789ABCDEF=
I need to convert the hexadecimal strings digit by digit into decimal and keep track if I need to borrow. I'm not sure how to adjust the value of operand 1 when a borrow occurs. Such as in the first line when you have to borrow 13 times.
Currently, I have
#include <iostream>
#include <fstream>
using namespace std;
string decimalToHex(int);
void subtraction(string, string)
int hexadecimalToDecimal(char hexVal);
int fullSubtractor(int tempOp1, int tempOp2)
int main()
{
ifstream myFile;
string l1, l2, l3, l4, l5, l6, l7, l8; //lines
string l1op1, l1op2, l2op1, l2op2, l3op1, l3op2, l4op1, l4op2, l5op1, l5op2, l6op1, l6op2, l7op1, l7op2, l8op1, l8op2; //parsed operators
myFile.open("data.txt");
if (myFile.is_open()) //check if file opened
{
cout << "File opened successfully. " << endl;
}
else
{
cerr << "File failed to open." << endl;
return 1;
}
while (!myFile.eof())
{
myFile >> l6 >> l7; //read in line by line
}
l6op1 = l6.substr(0, l6.find("-"));
l6op2 = l6.substr(l6.find("-") + 1);
l6op2 = l6op2.substr(0, l6op2.length() - 1);
std::string l6op2_zeros = std::string((l6op1.length()) - l6op2.length(), '0') + l6op2;
cout << l6; // << subtraction(l6op1, l6op2_zeros) << endl;
subtraction(l6op1, l6op2_zeros);
cout << endl;
l7op1 = l7.substr(0, l7.find("-"));
l7op2 = l7.substr(l7.find("-") + 1);
l7op2 = l7op2.substr(0, l7op2.length() - 1);
std::string l7op2_zeros = std::string((l7op1.length()) - l7op2.length(), '0') + l7op2; //appends zeros to front of second operand to make it same length as operand 1
cout << l7; // << subtraction(l7op1, l7op2) << endl;
subtraction(l7op1, l7op2_zeros);
cout << endl;
myFile.close();
return 0;
}
int fullSubtractor(int tempOp1, int tempOp2)
{
static int borrow;
int result = 0;
if ((tempOp1 < tempOp2) || ((tempOp1 == 0) && (borrow == 1)))
{
tempOp1 += 16;
result = tempOp1 - borrow - tempOp2;
borrow = 1;
}
else
{
result = tempOp1 - tempOp2;
borrow = 0;
}
return result;
}
void subtraction(string op1, string op2)
{
string result;
int tempDifference = 0, tempHex = 0;
int j = op2.length() - 1;
for (int i = op1.length() - 1; i >= 0; i--)
{
int temp1 = hexadecimalToDecimal(op1[i]);
int temp2 = hexadecimalToDecimal(op2[j]);
tempHex = fullSubtractor(temp1, temp2);
result = decimalToHex(tempHex) + result;
cout << result << " ";
j--;
}
cout << result << endl;
//return result;
}
int hexadecimalToDecimal(char hexVal)
{
int base = 1;
int dec_val = 0;
if (hexVal >= '0' && hexVal <= '9')
{
dec_val += (hexVal - 48) * base;
base *= 16;
}
else if (hexVal >= 'A' && hexVal <= 'F')
{
dec_val += (hexVal - 55) * base;
// incrementing base by power
base *= 16;
}
return dec_val;
}
string decimalToHex(int decNum)
{
stringstream ss;
ss << hex << decNum;
string hexNum(ss.str());
//cout << hexNum << endl;
return hexNum;
}

C++ binary input as a string to a decimal

I am trying to write a code that takes a binary number input as a string and will only accept 1's or 0's if not there should be an error message displayed. Then it should go through a loop digit by digit to convert the binary number as a string to decimal. I cant seem to get it right I have the fact that it will only accept 1's or 0's correct. But then when it gets into the calculations something messes up and I cant seem to get it correct. Currently this is the closest I believe I have to getting it working. could anyone give me a hint or help me with what i am doing wrong?
#include <iostream>
#include <string>
using namespace std;
string a;
int input();
int main()
{
input();
int decimal, x= 0, length, total = 0;
length = a.length();
// atempting to make it put the digits through a formula backwords.
for (int i = length; i >= 0; i--)
{
// Trying to make it only add the 2^x if the number is 1
if (a[i] = '1')
{
//should make total equal to the old total plus 2^x if a[i] = 1
total = total + pow(x,2);
}
//trying to let the power start at 0 and go up each run of the loop
x++;
}
cout << endl << total;
int stop;
cin >> stop;
return 0;
}
int input()
{
int x, x2, count, repeat = 0;
while (repeat == 0)
{
cout << "Enter a string representing a binary number => ";
cin >> a;
count = a.length();
for (x = 0; x < count; x++)
{
if (a[x] != '0' && a[x] != '1')
{
cout << a << " is not a string representing a binary number>" << endl;
repeat = 0;
break;
}
else
repeat = 1;
}
}
return 0;
}
I don't think that pow suits for integer calculation. In this case, you can use shift operator.
a[i] = '1' sets the value of a[i] to '1' and return '1', which is always true.
You shouldn't access a[length], which should be meaningless.
fixed code:
int main()
{
input();
int decimal, x= 0, length, total = 0;
length = a.length();
// atempting to make it put the digits through a formula backwords.
for (int i = length - 1; i >= 0; i--)
{
// Trying to make it only add the 2^x if the number is 1
if (a[i] == '1')
{
//should make total equal to the old total plus 2^x if a[i] = 1
total = total + (1 << x);
}
//trying to let the power start at 0 and go up each run of the loop
x++;
}
cout << endl << total;
int stop;
cin >> stop;
return 0;
}
I would use this approach...
#include <iostream>
using namespace std;
int main()
{
string str{ "10110011" }; // max length can be sizeof(int) X 8
int dec = 0, mask = 1;
for (int i = str.length() - 1; i >= 0; i--) {
if (str[i] == '1') {
dec |= mask;
}
mask <<= 1;
}
cout << "Decimal number is: " << dec;
// system("pause");
return 0;
}
Works for binary strings up to 32 bits. Swap out integer for long to get 64 bits.
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
string getBinaryString(int value, unsigned int length, bool reverse) {
string output = string(length, '0');
if (!reverse) {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << i)) != 0) {
output[i] = '1';
}
}
}
else {
for (unsigned int i = 0; i < length; i++) {
if ((value & (1 << (length - i - 1))) != 0) {
output[i] = '1';
}
}
}
return output;
}
unsigned long getInteger(const string& input, size_t lsbindex, size_t msbindex) {
unsigned long val = 0;
unsigned int offset = 0;
if (lsbindex > msbindex) {
size_t length = lsbindex - msbindex;
for (size_t i = msbindex; i <= lsbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << (length - offset));
}
}
}
else { //lsbindex < msbindex
for (size_t i = lsbindex; i <= msbindex; i++, offset++) {
if (input[i] == '1') {
val |= (1 << offset);
}
}
}
return val;
}
int main() {
int value = 23;
cout << value << ": " << getBinaryString(value, 5, false) << endl;
string str = "01011";
cout << str << ": " << getInteger(str, 1, 3) << endl;
}
I see multiple misstages in your code.
Your for-loop should start at i = length - 1 instead of i = length.
a[i] = '1' sets a[i] to '1' and does not compare it.
pow(x,2) means and not . pow is also not designed for integer operations. Use 2*2*... or 1<<e instead.
Also there are shorter ways to achieve it. Here is a example how I would do it:
std::size_t fromBinaryString(const std::string &str)
{
std::size_t result = 0;
for (std::size_t i = 0; i < str.size(); ++i)
{
// '0' - '0' == 0 and '1' - '0' == 1.
// If you don't want to assume that, you can use if or switch
result = (result << 1) + str[i] - '0';
}
return result;
}

why increment variable changing the value of the array when they have different names

Can someone please help me. I am struggling to find in my code why the last value in column B always gets incremented by one. I have written some code since its an assignment due today. I also cant figure out why the last value in column B is not equal to 196 because in the reset function it sets all the values in the array to 196 . Any suggestion would be appreciated. Thank you in advance
#include <iostream> //includes cin cout
#include <iomanip>
using namespace std; //setting up the environment
const int NUMBER_OF_ROWS = 3;
const int NUMBER_OF_COLUMNS = 3;
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats);
bool isFull(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
bool isEmpty(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
int main() { //main starts
int maxSeats;
int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
int SeatCountNumber = 0;
bool anyFreeSeats;
reset(seats);
anyFreeSeats = true;
SeatCountNumber = 0;
while (anyFreeSeats) {
printAllSeats(seats);
askForUsersSeat(seats, SeatCountNumber, anyFreeSeats);
}
system("pause");
return 0;
} //main ends
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) {
cout << endl;
cout << setw(10) << " - = Available R = Reserved\n\n";
for (int i = 0; i <= NUMBER_OF_ROWS; i++) {
cout << setw(15) << i << " ";
for (int j = 0; j < NUMBER_OF_COLUMNS; j++) {
if (i == 0) {
cout << " " << static_cast<char>(j + 65) << " ";
} else {
cout << " " << static_cast<char>(seats[i][j]) << " ";
}
}
cout << endl;
}
cout << endl;
}
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) {
//set all values in array to 196
for (int i = 0; i <= NUMBER_OF_ROWS; i++) {
for (int j = 0; j <= NUMBER_OF_COLUMNS; j++) {
seats[i][j] = 196;
}
}
}
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats) {
int seatChoiceNumber;
char seatChoiceLetter;
int letter;
int maxSeats = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS;
cout << "Seat (Row, Column): ";
cin >> seatChoiceNumber >> seatChoiceLetter;
letter = static_cast<int>(toupper(seatChoiceLetter));
if (((letter >= 65) && (letter < (65 + NUMBER_OF_COLUMNS))) && ((seatChoiceNumber > 0) && (seatChoiceNumber <= NUMBER_OF_ROWS))) {
if (seats[(seatChoiceNumber)][(letter - 65)] == 82) {
} else {
seats[(seatChoiceNumber)][(letter - 65)] = 82;
SeatCountNumber++; //this changes last value in column B for some reason
if (SeatCountNumber < maxSeats) {
anyFreeSeats = true;
}
else if (SeatCountNumber > maxSeats) {
printAllSeats(seats);
anyFreeSeats = false;
}
}
} else {
}
}
I kind of cleaned up the code a bit. It seems you found your answer in the comments, so I just did some indentation. Try and eliminate whitespaces in your code (mind you, the one I am putting here is not perfect either, but you get the point). Clean and easy to read code doesn't only make it better for you, but as you get higher up in the industry and other people begin reading and working on your code, having clean and easy to read code really helps :)
#include <iostream> //includes cin cout
#include <iomanip>
using namespace std; //setting up the environment
const int NUMBER_OF_ROWS = 3;
const int NUMBER_OF_COLUMNS = 3;
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats);
bool isFull(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
bool isEmpty(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
int main()
{
int maxSeats;
int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
int SeatCountNumber = 0;
bool anyFreeSeats;
reset(seats);
anyFreeSeats = true;
SeatCountNumber = 0;
while (anyFreeSeats)
{
printAllSeats(seats);
askForUsersSeat(seats, SeatCountNumber, anyFreeSeats);
}
system("pause");
return 0;
} //main ends
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS])
{
cout << endl;
cout << setw(10) << " - = Available R = Reserved\n\n";
for (int i = 0; i <= NUMBER_OF_ROWS; i++)
{
cout << setw(15) << i << " ";
for (int j = 0; j < NUMBER_OF_COLUMNS; j++)
{
if (i == 0)
{
cout << " " << static_cast<char>(j + 65) << " ";
}
else
{
cout << " " << static_cast<char>(seats[i][j]) << " ";
}
}
cout << endl;
}
cout << endl;
}
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS])
{
//set all values in array to 196
for (int i = 0; i <= NUMBER_OF_ROWS; i++)
{
for (int j = 0; j <= NUMBER_OF_COLUMNS; j++)
{
seats[i][j] = 196;
}
}
}
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats)
{
int seatChoiceNumber;
char seatChoiceLetter;
int letter;
int maxSeats = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS;
cout << "Seat (Row, Column): ";
cin >> seatChoiceNumber >> seatChoiceLetter;
letter = static_cast<int>(toupper(seatChoiceLetter));
if (((letter >= 65) && (letter < (65 + NUMBER_OF_COLUMNS))) && ((seatChoiceNumber > 0) && (seatChoiceNumber <= NUMBER_OF_ROWS)))
{
if (seats[(seatChoiceNumber)][(letter - 65)] == 82)
{
}
else
{
seats[(seatChoiceNumber)][(letter - 65)] = 82;
SeatCountNumber++; //this changes last value in column B for some reason
if (SeatCountNumber < maxSeats)
{
anyFreeSeats = true;
}
else if (SeatCountNumber > maxSeats)
{
printAllSeats(seats);
anyFreeSeats = false;
}
}
}
else {
}
}
Note: Some more whitespaces could even come out but I generally like to have spaces after certain statements (personal preference).

C++: Change of base function (i.e. hex to octal, decimal, etc.) - Output slightly off for hex values

I need to create a generic function that changes from any starting base, to any final base. I have everything down, except my original function took (and takes) an int value for the number that it converts to another base. I decided to just overload the function. I am Ok with changing between every base, but am slightly off when using my new function to take in a string hex value.
The code below should output 1235 for both functions. It does for the first one, but for the second, I am currently getting 1347. Decimal to Hex works fine - It's just the overloaded function (Hex to anything else) that is slightly off.
Thanks.
#include <iostream>
#include <stack>
#include <string>
#include <cmath>
using namespace std;
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num);
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s);
int main()
{
stack<int> myStack;
string hexNum = "4D3";
switchBasesFunction(myStack, 8, 10, 2323);
cout << endl << endl;
switchBasesFunction(myStack, 16, 10, hexNum);
return 0;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num)
{
int totalVal = 0;
string s = to_string(num);
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s)
{
int totalVal = 0;
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
Sorry, but I'm having issues understanding your code, so I thought I'd simplify it.
Here's the algorithm / code (untested):
void convert_to_base(const std::string& original_value,
unsigned int original_base,
std::string& final_value_str,
unsigned int final_base)
{
static const std::string digit_str =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ((original_base > digit_str.length()) || (final_base > digit_str.length())
{
std::cerr << "Base value exceeds limit of " << digit_str.length() << ".\n";
return;
}
// Parse string from right to left, smallest value to largest.
// Convert to decimal.
unsigned int original_number = 0;
unsigned int digit_value = 0;
int index = 0;
for (index = original_value.length(); index > 0; --index)
{
std::string::size_type posn = digit_str.find(original_value[index];
if (posn == std::string::npos)
{
cerr << "unsupported digit encountered: " << original_value[index] << ".\n";
return;
}
digit_value = posn;
original_number = original_number * original_base + digit_value;
}
// Convert to a string of digits in the final base.
while (original_number != 0)
{
digit_value = original_number % final_base;
final_value_str.insert(0, 1, digit_str[digit_value]);
original_number = original_number / final_base;
}
}
*Warning: code not tested via compiler.**