Error for c++ example - c++

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.

Related

Comparing two char pointers, but if pointer two has only 1 letter it doesn't work

int vorkommen(const char* s, const char* m) {
int lengthS = 0;
int lengthM = 0;
while (s[lengthS] != '\0') {
lengthS++;
}
while (m[lengthM] != '\0') {
lengthM++;
}
char textS[lengthS - 1];
char textM[lengthM - 1];
for(int i = 0; i < lengthS; i++) {
textS[i] = s[0];
s++;
}
for(int i = 0; i < lengthM; i++) {
textM[i] = m[0];
m++;
}
int match = 0;
for(int i = 0; i < lengthS; i++) {
for(int j = 0; j <= lengthM; j++) {
if(j == lengthM) {
match++;
} else if(textS[i + j] != textM[j]) {
break;
}
}
}
return match;
}
void Aufgabe_7() {
char first[256];
char second[256];
cin.getline(first, sizeof(first));
cin.getline(second, sizeof(second));
int test = vorkommen(first, second);
cout << test;
}
int main() {
Aufgabe_7();
return 0;
}
You see here a program which only task is it, to read in two texts and compare how often the text of the second char pointer is contained in the first char pointer.
For that I wrote this little program, it works and all but if the second char pointer contains only 1 letter the output of textS[0] is always equals to textM[0].

The roman character to integer convertion function is not working properly

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;
}

C putting floats in a 2D array puts random values

I take input from the user, calculate the number of rows and columns needed and put all the numbers in an array but it puts seemingly random values, it also duplicates some values i want to take the input from the user and put all the numbers in 2d array in order to do matrix operations
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define max_input_limit 99
float matrix_1[100][100];
float matrix_2[100][100];
float result[100][100];
int rows_1 = 0;
int cols_1 = 0;
void str_to_array1(char str[max_input_limit])
{
// sample input: [1 2 3, 4 5 6, 7 8 9]
// count number of commas
int rows = 1;
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == ',')
rows++;
}
rows_1 = rows;
// count number of spaces before first comma
int cols = 1;
for (int i = 0; str[i] != ','&&i<strlen(str); i++)
{
if (str[i] == ' ')
{
cols++;
}
}
cols_1 = cols;
//remove all commas and brackets from str
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == ',' || str[i] == '[' || str[i] == ']')
{
str[i] = ' ';
}
}
// fill 2D array
float arr[100][100];
for (int i = 0; str[i] != '\0'; i++)
{
for (int r = 0; r <= rows; r++)
{
for (int c = 0; c < cols; c++)
{
if (str[i] != ' ' && str[i+1] != NULL)
{
arr[r][c] = atof(&str[i]);
matrix_1[r][c] = arr[r][c];
cout << matrix_1[r][c]<<" ";
//if (arr[r][c] == rows+r)
//cout << ",";
i++;
}
}
}
}
}
void str_to_array2(char str[max_input_limit])
{
// sample input: [1 2 3, 4 5 6, 7 8 9]
// count number of commas
int rows = 1;
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == ',')
rows++;
}
rows_1 = rows;
// count number of spaces before first comma
int cols = 1;
for (int i = 0; str[i] != ','; i++)
{
if (str[i] == ' ')
cols++;
}
cols_1 = cols;
//remove all commas and brackets from str
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == ',' || str[i] == '[' || str[i] == ']')
{
str[i] = ' ';
}
}
// fill 2D array
float arr2[100][100];
for (int i = 0; str[i] != '\0'; i++)
{
for (int r = 0; r <= rows; r++)
{
for (int c = 0; c < cols; c++)
{
if (str[i] != ' ' && str[i + 1] != NULL)
{
arr2[r][c] = atof(&str[i]);
matrix_2[r][c] = arr2[r][c];
cout << matrix_2[r][c]<<" ";
//if (arr[r][c] == rows+r)
//cout << ",";
i++;
}
}
}
}
}
void add(float result[100][100], float matrix_1[100][100], float matrix_2[100][100])
{
cout << "[";
for (int r = 0; r < rows_1; r++)
{
for (int c=0; c < cols_1; c++)
{
result[r][c] = matrix_1[r][c] + matrix_2[r][c];
cout << result[r][c] << " ";
}
}
cout << "]";
}
int main()
{
char str[99];
char str2[99];
cin.getline(str, 99);
str_to_array1(str);
cin.ignore();
cin.getline(str2, 99);
str_to_array2(str2);
}
When i put
[1 2 33, 4 55 6]
I get output
[1 2 33 3 4 55 5 6 ]

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:

Convert decimal to binary in big number

I want to create a big number with 128 bit.
When I convert the string decimal to binary and set bit to the new data QInt :__int64 a[2], it only true for a small number (about 10 digits).
This is my code: http://codepad.org/HmYqMQme
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
//new data
class QInt
{
private:
__int64 a[2];
public:
void Get()
{
cout << a[0] << endl;
cout << a[1] << endl;
}
QInt()
{
a[0] = 0;
a[1] = 0;
}
//the funtion get the string binary of a[1]
char* GetQInt(char *A);
//the devide two of string decimal
char* Div2(char *Str);
//the funtion set bit to a[0] and a[1]
void Setbit(int i, int bit);
//con vert decimal to binary
QInt ConvertDecimalToBinary(char *De, char *Bi);
};
//the funtion get the string binary of a[1]
char *QInt::GetQInt(char *A)
{
for (int i = 0; i < 64; i++)
{
if (((a[1] >> i) & 1) != 0)
{
A[63 - i] = 49;
}
else
{
A[63 - i] = 48;
}
}
return A;
}
// the funtion set bit to a[0] and a[1]
void QInt:: Setbit(int i, int bit)
{
//if i<64 we set bit to a[1]
if (i < 64)
{
if (bit==1)
{
a[1]=(1 << i) | a[1];
}
}//similar to a[1]
else
{
if (bit == 1)
a[0]=(1 << i) | a[0];
}
}
//the devide two of string decimal
char*QInt:: Div2(char *Str)
{
char Arr[100];
int n = strlen(Str);
int a = 0;//lay phan du
int i = 0;
int j = 0;
while (Str[i] == 0)
{
i++;
}
for (i; i < n; i++)
{
int c = Str[i] - 48 + a * 10;
a = c % 2;
Arr[j] = c / 2 + 48;
j++;
}
Arr[i] = '\0';
for (i = 0; i < strlen(Arr); i++)
{
Str[i] = Arr[i];
}
Str[i] = '\0';
return Str;
}
//con vert decimal to binary
QInt QInt::ConvertDecimalToBinary(char *De,char *Bi)
{
int bit;
int i = 127;
int lenth = strlen(De);
while (1)
{
//variable h use to count the number 0 of the string decimal,if h=lenth,exit
int k = 0;
int h = 0;
while (De[k])
{
if (De[k] == '0')
h++;
k++;
}
if (h == lenth)
break;
else
{
bit = (De[lenth - 1] - 48) % 2;
Bi[i] = bit + 48;
Setbit(127 - i, bit);
De = Div2(De);
i--;
}
}
Bi[128] = NULL;
return *this;
}
int main()
{
char s[100];
char b[200];
char c[200];
for (int i = 0; i < 128; i++)
{
b[i] = 48;
}
cout << "Please enter a string : ";
gets_s(s, 99);
QInt a;
a.ConvertDecimalToBinary(s, b);
a.Get();
a.GetQInt(c);
for (int i = 0; i < 64; i++)
cout << b[i];
cout << endl;
for (int i = 64; i < 128; i++)
cout << b[i];
cout << endl;
for (int i = 0; i < 64; i++)
{
cout << c[i];
}
cout << endl;
system("pause");
return 0;
}
If i==100, what do you think (1 << i) does? What should it do? And why are you ignoring a[0] in GetQInt ?
In general, you have quite a few problems. You're not comfortable with std::string, and making a mess of the char* everywhere. You're not clearly articulating (not even to yourself) what methods are supposed to be doing. You're putting mathods in a class that are unrelated to the class. Even worse, some of those methods redefine the name a ! That is very confusing.