The roman character to integer convertion function is not working properly - c++

I am getting segmentation fault to this code to convert roman numerals to numbers, i am getting segmentation error when i try the program in https://www.programiz.com/cpp-programming/online-compiler/ and i found that the inside of the loop A is never executed in my case
#include<iostream>
#include<conio.h>
#include<cstring>
using namespace std;
char str[50];
int a[50],m=50,val=0;
int intit(){
m=strlen(str);
for(int i=0;i<m;i++){//loop A
cout<<i;
if(str[i]=='M'){a[i]=1000;}
if(str[i]=='D'){a[i]=500;}
if(str[i]=='C'){a[i]=100;}
if(str[i]=='L'){a[i]=50;}
if(str[i]=='X'){a[i]=10;}
if(str[i]=='V'){a[i]=5;}
if(str[i]=='I'){a[i]=1;}
}
return 0;
}
int main(){
char str[50];
int a[50],m,val=0;
cin>>str;
cout<<"exit val" +char(intit());
for(int i=m-1;i>=0;i--){ //loop B
cout<<"inside evaluation loop"<<a[i];
if(a[i+1]>a[i]){val = val - a[i];}
else{val = val + a[i];}
}
cout<<"\n\n\nans:"<<val;
getch();
}

You use global and local variable with the same name. remove one of them and the program work correctly.
However it is better to send your parameter by reference than define global parameter:
int intit(char (& str)[50], int (&a)[50],int &m ,int &val ) {
m = strlen(str);
for (int i = 0;i < m;i++) {//loop A
cout << i;
if (str[i] == 'M') { a[i] = 1000; }
if (str[i] == 'D') { a[i] = 500; }
if (str[i] == 'C') { a[i] = 100; }
if (str[i] == 'L') { a[i] = 50; }
if (str[i] == 'X') { a[i] = 10; }
if (str[i] == 'V') { a[i] = 5; }
if (str[i] == 'I') { a[i] = 1; }
}
return 0;
}
int main() {
char str[50];
int a[50], m = 50, val =0;
cin >> str;
cout << "exit val" + char(intit(str,a,m,val));
for (int i = m - 1;i >= 0;i--) { //loop B
cout << "inside evaluation loop" << a[i];
if (a[i + 1] > a[i]) { val = val - a[i]; }
else { val = val + a[i]; }
}
cout << "\n\n\nans:" << val;
}

Related

Why the simple multiplication would result in some garbled characters?

I try to design a program that implements the multiplication between two big integers(Using C++). But after I complete it, I found that if I input the two integers by the command arguments, the results would be sometimes very weird and sometimes right. Please help me figure out the reason and tell me how to fix it. Thanks (The main function that implements the function of multiplication between two big integers is mul() ).
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
void mul(char *c1, char *c2, int len1, int len2);
void printArr(char *c1, char *c2, int len1, int len2);
int main(int argc, char **argv)
{
if (argv[1] != NULL)
{
char cArr1[500], cArr2[500];
for (int i = 0; i < strlen(argv[1]); i++)
{
cArr1[i] = argv[1][i];
}
for (int i = 0; i < strlen(argv[2]); i++)
{
cArr2[i] = argv[2][i];
}
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
exit(100);
}
while (true)
{
cout << "Please input two integers" << endl;
char cArr1[500], cArr2[500];
cin >> cArr1;
if (cArr1[0] == 'q' && cArr1[1] == 'u' && cArr1[2] == 'i' && cArr1[3] == 't')
{
exit(1000);
}
cin >> cArr2;
int parity = 0;
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
if (cArr1[0] == '-')
{
for (int i = 1; i < len1; i++)
{
cArr1[i - 1] = cArr1[i];
}
parity++;
len1--;
}
if (cArr2[0] == '-')
{
for (int i = 1; i < len2; i++)
{
cArr2[i - 1] = cArr2[i];
}
parity++;
len2--;
}
bool isDigit = true;
for (int i = 0; i < len1; i++)
{
if (!isdigit(cArr1[i]))
{
isDigit = false;
}
}
for (int i = 0; i < len2; i++)
{
if (!isdigit(cArr2[i]))
{
isDigit = false;
}
}
if (!isDigit)
{
cout << "\rInvalid input. Try again" << endl;
continue;
}
if (parity % 2 != 0)
{
cout << "-";
}
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
}
}
void mul(char *bigger, char *smaller, int bigLen, int smallLen)
{
int *bigNum = new int[bigLen];
int *smallNum = new int[smallLen];
for (int i = 0; i < bigLen; i++)
{
bigNum[i] = bigger[bigLen - i - 1] - '0';
}
for (int i = 0; i < smallLen; i++)
{
smallNum[i] = smaller[smallLen - i - 1] - '0';
}
int res[30];
for (int i = 0; i < 30; i++)
{
res[i] = 0;
}
for (int i = 0; i < smallLen; i++)
{
for (int j = 0; j < bigLen; j++)
{
res[i + j] += bigNum[j] * smallNum[i];
}
}
for (int i = 0; i < bigLen + smallLen; i++)
{
int digit = res[i] % 10;
int carry = res[i] / 10;
res[i] = digit;
res[i + 1] += carry;
}
bool null = false;
for (int i = bigLen + smallLen - 1; i >= 0; i--)
{
if (res[i] != 0 && res[i + 1] == 0)
{
null = true;
}
if (null)
{
cout << res[i];
}
}
cout << endl;
}
void printArr(char *c1, char *c2, int len1, int len2)
{
for (int i = 0; i < len1; i++)
{
cout << c1[i];
}
cout << " * ";
for (int i = 0; i < len2; i++)
{
cout << c2[i];
}
cout << " = ";
}
Just initialize your char arrays to empty ones:
char cArr1[500] = {};
char cArr2[500] = {};
then, for the sake of clarity, assign the lengths from your arguments to two integers, casting them since the compiler might warn you about incompatibility between size_t and int.
int lenArg1 = 0;
int lenArg2 = 0;
lenArg1 = (int)strlen ( argv[1] );
lenArg2 = (int)strlen ( argv[2] );
Then, printing the lengths len1 and len2 for debugging purposes only:
int len1 = strlen ( cArr1 );
int len2 = strlen ( cArr2 );
cout << "len1 >> " + to_string(len1) <<endl;
cout << "len2 >> " + to_string(len2) <<endl;
In fact, as #Kevin SUN mentioned, it was possible that your argument reading steps were missing the null characters, however, after running some tests it seems to work fine just by initializing the char arrays.
Also, as mentioned in the comments you need to increase the size reserved for res array, I did it to 500
Compiled with g++ -Wall main.cpp -o calc.exe and running: calc 10 100
Without initialization you get problems like:
after initializing, the output works just fine:

how to extract the coefficients and exponent of a polynomial as string

hello my problem is that i have to extract the coefficients and exponent of a polynomial given by the user.
when i tried my code it just worked for the coefficient, and for the exponent it gives me a zero. p.s a is just for testing
int main() {
char x[10];
char y[10];
char a[100] = "53x2+4x^3";
for (int i = 0; a[i] != '+'; i++)
{
if (a[i] != 'x')
{
x[i] = a[i];
}
}
for (int i = 0; a[i] != '+'; i++)
{
if ((a[i] == 'x') && (a[i + 1] == '^')) {
y[i] = a[i + 2];
}
}
double w;
int z;
w = atof(x);
z = atoi(y);
cout << w << endl;
cout << z << endl;
return 0;
}
You need to initialize your coefficient and exponent buffers with null terminators so that they are properly null terminated when the output console reads them.
#include <iostream>
using namespace std;
int main() {
char x[10] = {'\0'};
char y[10] = {'\0'};
char a[100] = "53x^2+4x^3";
for (int i = 0, j = 0; a[i] != '+'; i++)
{
if (a[i] != 'x')
{
x[j] = a[i];
j++;
}
}
for (int i = 0, j = 0; a[i] != '+'; i++)
{
if ((a[i] == 'x') && (a[i + 1] == '^')) {
y[j] = a[i + 2];
j++;
}
}
double w;
int z;
w = atof(x);
z = atoi(y);
cout << w << endl;
cout << z << endl;
return 0;
}

Error for c++ example

I want to input alphabet to binary code, and output the alphabet from generated binary code.
Example
1 --> a
01 --> b
001 --> c
0001 --> d
00001 --> e
000001 --> f
a => 1
b => 01
c => 001
d => 0001
e => 00001
-------------Encode.cpp--------------------
#include "Encode.h"
Encode::Encode()
{
}
Encode::~Encode()
{
}
void Encode::inputWord()
{
cout << "Input word: ";
cin.getline(word, 255);
return;
}// User input a word
char * Encode::getBuf(void)
{
return buffer;
}// return buffer to Decode::setBuf(char* buf)
void Encode::printEncResult()
{
int size = strlen(word);
int buffersize = 0;
cout << "Encoding result" << endl; // print similar binary
for (int i = 0; i < size; i++)
{
if (word[i] == 'z')
{
for (int j = 0; j < 25; j++)
{
cout<<buffer[buffersize++];
}
}
else
{
int len = (int)word[i] - (int)'a';
for (int j = 0; j < len; j++)
{
cout<<buffer[buffersize++];
}
cout << buffer[buffersize++];
}
}
}// output similar binary
int Encode::encodeWord(void)
{
int buffersize = 0;
int size = strlen(word);
for (int i = 0; i < size; i++)
{
if (word[i] == 'z')
{
for (int j = 0; j < 25; j++)
{
buffer[buffersize++] = '0';
}
}
else
{
int len = (int)word[i] - (int)'a';
for (int j = 0; j < len; j++)
{
buffer[buffersize++] = '0';
}
buffer[buffersize++] = '1';
}
}
return 0;
}// change word to similar binary
--------Decode.cpp-------------
#include "Decode.h"
Decode::Decode()
{
}
Decode::~Decode()
{
}
void Decode::setBuf(char * buf)
{
int i = 0;
int size = 0;
while (*(buf + i) == '1' || *(buf + i) == '0')
{
i++;
}
size = i;
for(int i = 0; i < size; i++)
{
buffer[i] = buf[i];
}
return;
}// set buffer from Encode::getBuf(void)
void Decode::printWord() // print similar binary
{
int i = 0;
int size = 0;
int check = 1;
while (check)
{
if (word[i] >= 'a' && (int)word[i] <= 'z')
{
i++;
size = i;
}
else
check = 0;
}
cout << "Decoding result" << endl;
for (int i = 0; i < size; i++)
{
if (word[i] >= 'a' && (int)word[i] <= 'z') // **this part is also strange** I can not shoten the code.
cout<<word[i];
}
cout << endl;
}
int Decode::decodebin(vector<char> buffer)
{
int buffersize = 0;
int check = 0;
int size = 0;
int i = 0;
char printval = 'a';
while (buffer[i] == '1' || buffer[i] == '0')
{
i++;
}
size = i;
for (int j = 0; j < size; j++) // nested loop does not work. I want save words in order
{
for (i = 0; i < size; i++)
{
if (buffer[i] == '0')
++printval;
else
{
word[j] = printval; // In this part, word[0] does not have any value.
printval = 'a';
}
}
}
return 0;
}
In this code, I want save values in order, but word[0] does not have any value. Moreover, If I input 'bb' then, 'bbbb' saved ins word array.
There are some problems and consideration you need to take care of:
as Fei Xiang said in the comments don't use magic numbers, use characters since you have a character array.
int printWord function you actually get the word and print the same word, there is no conversion as your problem statement. your didn't take buffer into account.
you are using some data validation to get your array size, this could end up a disaster(UB). you need to pass your array size to your function or use std::vector(Recommended).
in this statement if ((int)word[i] >= 97 || (int)word[i] <= 122) as I said don't use magic number and || should be change to && otherwise you end up in an infinity loop.
Anyway by keeping your approach(using array) and function signature here's what you can do :
int Decode::decodebin(void)
{
int buffersize = 0;
int check = 0;
int size = 0;
int i = 0;
char printval = 'a';
while(buffer[i] == '1' || buffer[i] == '0')
{
i++;
size = i;
}
for(int i = 0; i < size; i++)
{
if(buffer[i] == '0')
++printval;
else
{
cout << printval;
printval = 'a';
}
}
return 0;
}
void Decode::printWord()
{
int i = 0;
int size = 0;
int check = 1;
while(check)
{
if(word[i] >= 'a' && word[i] <= 'z')
{
i++;
size = i;
}
else
check = 0;
}
cout << "Decoding result" << endl;
for(int i = 0; i < size; i++)
{
int distance = word[i] - 'a';
for(int j = 0; j < distance; ++j)
cout << '0';
cout << '1';
}
cout << endl;
}
EDIT BASED ON OP REQUIREMENT IN COMMENTS:
using std::vector you can implement your needs like this :
#include <iostream>
#include <vector>
class Decode
{
public:
void decodebin(std::vector<char> buffer)
{
char printval = 'a';
for(unsigned int i = 0; i < buffer.size(); i++)
{
if(buffer[i] == '0')
++printval;
else
{
word.push_back(printval);
printval = 'a';
}
}
}
void printWord(void)
{
for(auto iter = word.begin(); iter != word.end(); ++iter)
std::cout << *iter;
std::cout << std::endl;
}
private:
std::vector<char> word;
};
int main()
{
Decode decoder;
std::vector<char> buffer = {'0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '1'};
decoder.decodebin(buffer);
decoder.printWord();
return 0;
}
Here decodebin stores the given input into word member variable of Decode class. Then printWord function print word values on the screen.
std::vector has all the power of C-style array and it's nicer and easier to use. You can retrieve it's size whenever you want and you don't have to worry about the memory it's allocating.

Reading from file.txt to array of strings and using it to play Conway's game of Life

I am coding a Conway's Game of Life.My task is reading from file.txt to array of strings.And then using this array as the input array of the game. I have written a code about it. But it is full of error. I don't know what is the correct way to do this.
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>
using namespace std;
namespace gamearray {
int main()
ifstream file_("file.txt");
if(file.is_open())
{
string myArray[10];
for(int i = 0; i < 10; ++i)
{
for(int i = 0; i < 10; i++)
file >> array1[j][i];
}
}
return 0;
}
void copy(int array1[10][10], int array2[10][10])
{
for(int j = 0; j < 10; j++)
{
for(int i = 0; i < 10; i++)
array2[j][i] = array1[j][i];
}
}
void life(int array[10][10], char choice)
{
int temp[10][10];
copy(array, temp);
for(int j = 0; j < 10; j++)
{
for(int i = 0; i < 10; i++)
{
if(choice == 'm')
{
int count = 0;
count = array[j-1][i] +
array[j-1][i-1] +
array[j][i-1] +
array[j+1][i-1] +
array[j+1][i] +
array[j+1][i+1] +
array[j][i+1] +
array[j-1][i+1];
if(count < 2 || count > 3)
temp[j][i] = 0;
if(count == 2)
temp[j][i] = array[j][i];
if(count == 3)
temp[j][i] = 1;
}
}
}
copy(temp, array);
}
bool compare(int array1[10][10], int array2[10][10])
{
int count = 0;
for(int j = 0; j < 10; j++)
{
for(int i = 0; i < 10; i++)
{
if(array1[j][i]==array2[j][i])
count++;
}
}
if(count == 10*10)
return true;
else
return false;
}
void print(int array[10][10])
{
for(int j = 0; j < 10; j++)
{
for(int i = 0; i < 10; i++)
{
if(array[j][i] == 1)
cout << '*';
else
cout << ' ';
}
cout << endl;
}
}
int main()
{gamearray::main();
int gen0[10][10];
int todo[10][10];
int backup[10][10];
char neighborhood;
char again;
char cont;
bool comparison;
{do
{
do
{
cout << "Which neighborhood would you like to use (m): ";
cin >> neighborhood;
}while(neighborhood != 'm');
system("CLS");
int i = 0;
do
{
srand(time(NULL));
for(int j = 0; j < 10; j++)
{
for (int i = 0; i < 10; i++)
gen0[j][i] = rand() % 2;
}
if(i == 0)
copy(gen0, todo);
copy(todo, backup);
print(todo);
life(todo, neighborhood);
i++;
system("sleep .5");
if(i % 10 == 1 && i != 1)
{
cout << endl;
do
{
cout << "Would you like to continue this simulation? (y/n): ";
cin >> cont;
}while(cont != 'y' && cont != 'n');
if(cont == 'n')
break;
}
comparison = compare(todo, backup);
if(comparison == false)
system("CLS");
if(comparison == true)
cout << endl;
}while(comparison == false);
do
{
cout << "Would you like to run another simulation? (y/n): ";
cin >> again;
}while(again != 'y' && again != 'n');
}while(again == 'y');
return 0;
}
}
/*
* spielm.cpp
*
* Created on: 22.09.2016
* Author: fislam
*/
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
using namespace std;
void GetFile();
bool MakeArray();
char ChgArray();
//char GameBoard();
const int ROW1 =10;
const int COL1 =10;
const int BOARD_ROWS(10);
const int BOARD_COLS(10);
ifstream myfile;
string filename;
char live = 'X';
char dead = '.';
char board [BOARD_ROWS][BOARD_COLS];
int main()
{
int q;
//GetFile();
if ( MakeArray() ){
for ( int i(0); i <10; i++)
ChgArray();
}
else {
cout << "Error parsing input file" << endl;
}
cin >> q;
return 0;
}
void GetFile()
{
cout<<"Enter the filename: \n";
cin>>filename;
return;
}
bool MakeArray()
{
bool ret(false);
char val;
int totCnt = BOARD_ROWS*BOARD_COLS;
myfile.open (/*filename.c_str()*/"c_str.txt");
if ( myfile.is_open() ) {
for (int r=0; r<ROW1; r++)
{
for (int c=0; c<COL1; c++)
{
myfile>>val;
if ( val == dead || val == live ) {
board[r-1][c-1] = val;
totCnt--;
}
}
}
if ( !totCnt ) {
ret = true;
}
myfile.close();
}
return ret;
}
char getNextState(char b[BOARD_ROWS][BOARD_COLS], int r, int c)
{
char ret;
return ret;
}
char ChgArray()
{
char boardTmp[BOARD_ROWS][BOARD_COLS];
for (int r=0; r<BOARD_ROWS; r++)
{
for (int c=0; c<BOARD_COLS; c++)
{
boardTmp[r][c] = getNextState(board,r,c);
cout << boardTmp[r][c];
}
cout<<endl;
}
memcpy(board,boardTmp,sizeof(board));
cout << endl;
}
Instead of the previous I wrote new. and it worked
aftert main you are missing {
in first and second loop you have i loop twice
why do you need to copy ?
you can use this function fscanf() to read your file
e.g.
File= fopen(FileName, "r");
if( File == NULL ){
printf("Impossible to open file %s ! \n",FileName);
}
if( File != NULL)
{
char text[255];
while(!feof(File))
{
fscanf(File,"%s\n",&text);
....
}
}

Sudden variable reset

Problem:
"maxPrint" resets to 0 out of nowhere.
In function "skaitymas" it complies to if, and changes itself to "p" finding the biggest one.
After the function is done, "maxPrint" suddenly becomes 0 again...
maxPrint is not even used anywhere after that..
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
const char duomF[] = "1.txt";
const char rezF[] = "rez1.txt";
const int CMax = 81;
void reset(int SK[])
{
for (int i = 0; i < CMax; i++)
{
SK[i] = 0;
}
}
void skaitymas(int SK[], int &n, int &maxPrint)
{
ifstream df(duomF);
char temp;
int tempsk;
int p;
df >> n;
for (int i = 0; i < n; i++)
{
df >> p;
if (p > maxPrint)
{
maxPrint = p;
}
cout << p << " " << maxPrint << endl;
for (int j = CMax - p; j < CMax; j++)
{
df >> temp;
{ if (temp == '0') tempsk = 0;
else if (temp == '1') tempsk = 1;
else if (temp == '2') tempsk = 2;
else if (temp == '3') tempsk = 3;
else if (temp == '4') tempsk = 4;
else if (temp == '5') tempsk = 5;
else if (temp == '6') tempsk = 6;
else if (temp == '7') tempsk = 7;
else if (temp == '8') tempsk = 8;
else if (temp == '9') tempsk = 9;
}
SK[j] += tempsk;
}
}
df.close();
}
void skaiciavimas(int SK[])
{
int temp;
for (int i = CMax; i >= 0; i--)
{
if(SK[i] >= 10)
{
temp = SK[i] / 10;
SK[i-1] += temp;
SK[i] = SK[i] % 10;
}
}
}
int main()
{
int SK[CMax];
int n; int maxPrint = 0;
reset(SK);
skaitymas(SK, n, maxPrint);
skaiciavimas(SK);
for (int i = CMax - (maxPrint - 1); i < CMax; i++) cout << SK[i] << " ";
cout << maxPrint << endl;
ofstream rf(rezF);
for (int i = CMax - (maxPrint - 1); i < CMax; i++) rf << SK[i];
rf.close();
return 0;
}
In this loop you are accessing SK out of bounds:
void skaiciavimas(int SK[])
{
int temp;
for (int i = CMax; i >= 0; i--)
{
if(SK[i] >= 10) //<<< BUG (i = CMax)
{
temp = SK[i] / 10; //<<< BUG (i = CMax)
SK[i-1] += temp; //<<< BUG (i = 0)
SK[i] = SK[i] % 10; //<<< BUG (i = CMax)
}
}
}
Note that valid indices for SK are from 0 to CMax - 1, so accessing SK[CMax] results in undefined behaviour, as does accessing SK[-1].
Note that when you write to an array out of bounds you may well overwrite adjacent variables, which probably explains the unexpected modification of maxPrint, but as with any case of undefined behaviour, literally anything can happen.
Without knowing what your code is supposed be doing I can only guess that perhaps your for loop should be:
for (int i = CMax - 1; i > 0; i--)