Using Array as parameter in function in C++ - c++

This program gets two hexadecimal numbers and converts them to decimal numbers. And it finally returns sum of two number in decimal form.
Before I enter "num2", "n1" gets right value.
But "n1" becomes 0 after I get "num2".
I don't know why this happens.
Please tell me the reason in hurry...
#include <iostream>
using namespace std;
class HextoDec {
public:
void getNum();
int add();
private:
char num1[2], num2[2];
int convert(char num[]);
int n1, n2;
};
int main()
{
HextoDec a;
a.getNum();
cout << "Sum of two number is " << a.add() << endl;
}
void HextoDec::getNum() {
cout << "Enter first number : ";
cin >> num1;
n1 = convert(num1);
cout << "Enter second number : ";
cout << endl << n1 << endl; // Value of n1 is correct
cin >> num2;
cout << n1 << endl; // Problem occurs. Value of n1 becomes 0
n2 = convert(num2);
}
int HextoDec::convert(char num[]) {
int j = 16, n = 0;
for (int i = 0 ; i < 2 ; i++) {
switch (num[i]) {
case '0':
n = n + j * 0; break;
case '1':
n = n + j * 1; break;
case '2':
n = n + j * 2; break;
case '3':
n = n + j * 3; break;
case '4':
n = n + j * 4; break;
case '5':
n = n + j * 5; break;
case '6':
n = n + j * 6; break;
case '7':
n = n + j * 7; break;
case '8':
n = n + j * 8; break;
case '9':
n = n + j * 9; break;
case 'A':
n = n + j * 10; break;
case 'B':
n = n + j * 11; break;
case 'C':
n = n + j * 12; break;
case 'D':
n = n + j * 13; break;
case 'E':
n = n + j * 14; break;
case 'F':
n = n + j * 15; break;
}
j = 1;
}
return n;
}
int HextoDec::add() {
cout << "*****" << endl;
cout << n1 << endl;
cout << n2 << endl;
return n1 + n2;
}
What's the reason?
What makes this happens?
What can I do or should I do to solve this problem?

As other people have mentioned, your char arrays only contain one element, plus the '\0' character. If you try to read with cin a two character array (i.e. 1a) you will have a undefined behaviour. This example might give you some hints about '\0'
const char *example1 = "hi";
strlen(example1); // This is 2
const char *example1 = "hi\0";
strlen(example1); // This is also 2
But answering to your question, if you only want to read 2-digit hexadecimal values, char num1[3] should fix the issue.
However, I think you might have another issue. Just copied/pasted your code and if I enter just 1 the result that I get is 16, but it should be 1. Maybe you expect the user to input 01 instead.
I guess this is a didactic example, so you might want to play a bit with the code, and for example be able to convert any number to decimal. Maybe you can modify your function convert with something like:
int HextoDec::convert(char num[]) {
int n = 0;
int sizeNumber = strlen(num);
for (int i = sizeNumber - 1; i >= 0; i--)
{
int j = pow(16, sizeNumber - i - 1);
...
}

Related

string subscript out of range in C++ for Cowculations

Please help with debugging.
It gives me an error 'string subscript out of range error' after the fifth input.
I was unable to figure out what to change.
Here is the code:
#include <iostream>
#include <string>
#define N 100
int str2int(std::string input)
{
int num = 0;
for (int i = 0; i < input.length(); i++)
{
if (input[i] == 'V')
num *= 4 + 0;
else if (input[i] == 'U')
num *= 4 + 1;
else if (input[i] == 'C')
num *= 4 + 2;
else if (input[i] == 'D')
num *= 4 + 3;
}
return num;
}
int main(void)
{
int tablet = 0, num1 = 0, num2 = 0, ans = 0;
std::string cowNum1 = "", cowNum2 = "", result = "";
std::string operation = "";
std::cin >> tablet;
std::cout << "COWCULATIONS OUTPUT" << std::endl;
while (tablet--)
{
std::cin >> cowNum1 >> cowNum2;
num1 = str2int(cowNum1);
num2= str2int(cowNum2);
for (int oprt = 0; oprt < 3; oprt++)
{
std::cin >> operation[oprt];
switch (operation[oprt])
{
case 'A':
{
num2 += num1;
break;
}
case 'R':
{
num2 >>= 2;
break;
}
case 'L':
{
num2 <<= 2;
break;
}
case 'N':
default:
break;
}
}
std::cin >> result;
ans = str2int(result);
if (num2 == ans)
std::cout << "YES" << std::endl;
else
std::cout << "NO" << std::endl;
std::cout << "END OF OUTPUT" << std::endl;
}
return 0;
}
Question is from 377 - Cowculations
Sample Input
5
VVVVU
VVVVU
A
A
A
VVVVVVUV
VVCCV
VVDCC
L
R
A
VVVVUCVC
VVCCV
VVDCC
R
L
A
VVVVUCVV
VVUUU
VVVVU
A
N
N
VVVVVUCU
DDDDD
VVVVU
A
L
L
UVVVVVVV
You may not use the subscript operator for an empty string to change its value
std::cin >> operation[oprt];
At least you have to declare the object operation with the magic number 3 used in your for loop. For example
std::string operation( 3, '\0' );
Or
std::string operation;
operation.resize( 3 );
If you need to enter only one characters in a loop then an object of the type std::string is not required. You could just write
for (int oprt = 0; oprt < 3; oprt++)
{
char c;
std::cin >> c;
switch ( c )
{
case 'A':
{
num2 += num1;
break;
}
case 'R':
{
num2 >>= 2;
break;
}
case 'L':
{
num2 <<= 2;
break;
}
case 'N':
default:
break;
}
}

Is this the right way? How to get Hex value into a char array?

I need following char packet[] = {0x00,0x14}; to send over a TCP/IP, this is the only way I got it to work. With that char I would send the number 20, another possible example would be char packet[] = {0x4e,0x20}; that would be 20000. I am Starting to think that I am approaching this completely wrong.
With this code I can print the Hex value of an Int out.
#include <iostream>
using namespace std;
int main() {
int num, temp, i = 1, j,k=1, r;
char hex[50] = {};
char paket[7] = {'0','x'};
cout << "Input?";
cin >> num;
temp = num;
while (temp != 0) {
r = temp % 16;
if (r < 10)
hex[i++] = r + 48;
else
hex[i++] = r + 55;
temp = temp / 16;
}
cout << i << endl;
cout << "\nHex = ";
for (j = i; j > 0; j--) {
cout << hex[j];
switch (k)
{
case 1:
paket[2] = { hex[j] };
break;
case 2:
paket[3] = { hex[j] };
break;
case 3:
paket[4] = { hex[j] };
break;
case 4:
paket[5] = { hex[j] };
break;
}
k++;
}
cout << endl << paket;
return 0;
This part is how I am trying to get the format I need, but sadly it's not working.
switch (k)
{
case 1:
paket[2] = { hex[j] };
break;
case 2:
paket[3] = { hex[j] };
break;
case 3:
paket[4] = { hex[j] };
break;
case 4:
paket[5] = { hex[j] };
break;
}
k++;
If you just want to convert a number than can be expressed in 16-bits into an array of 2 bytes using network byte order as you imply.
int num = 20000; // or any number for that matter
char packet[2];
packet[0] = (num & 0xff00)>>8; // 0x4E
packet[1] = (num & 0x00ff); // 0x20
Done.
Alternatively, most network programming uses memcpy to byte-pack integers into byte arrays:
uint16_t num = 20000;
char packet[2];
memcpy(packet, &num, 2);
The only problem is that on Little Endian platforms, such as all Intel chips, the above code will write {0x20, 0x4E} into the array. The bytes will be in the wrong order. There's a helper function that swaps those bytes out called htons. The header files to import htons and similar functions vary between OS platform, but is available everywhere.
uint16_t num = 20000;
char packet[2];
num = htons(num); // swaps bytes on little endian, no-op on big-endian
memcpy(packet, &num, 2);

Number System in C++

I have a program that should translate values ​​from one number system to another, but I have a problem with "_itoa_s" writes that [Error] '_itoa_s' was not declared in this scope I tried to connect libraries <cstdlib> and <stdlib.h> I also tried replacing itoa with "snprintf" but it does not help in the compiler there are even more errors, please help me fix the error,
Here is the code:
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
setlocale(LC_ALL, "rus");
int in, iz, k, s = 0, p;
char str[255];
cout << "Enter the number system from which you want to translate" << endl;
cin >> iz;
cout << "Enter the number system to which we will translate" << endl;
cin >> in;
cout << "Enter the number" << endl;
cin >> str;
p = strlen(str) - 1;
for (int i = 0; i < str[i]; i++)
{
switch (str[i])
{
case 'a': k = 10; break;
case 'b': k = 11; break;
case 'c': k = 12; break;
case 'd': k = 13; break;
case 'e': k = 14; break;
case 'f': k = 15; break;
case '1': k = 1; break;
case '2': k = 2; break;
case '3': k = 3; break;
case '4': k = 4; break;
case '5': k = 5; break;
case '6': k = 6; break;
case '7': k = 7; break;
case '8': k = 8; break;
case '9': k = 9; break;
case '0': k = 0; break;
}
s = s + k * pow(iz, p);
p--;
}
char result[255];
_itoa_s(s, result, in);
cout << "The result of a translation from a radix " << iz << " to radix " << in << " = " << result;
return 0;
}
Here's an alternative that doesn't involve switch, pow or itoa:
// Notice, the index is the value of the digit.
const std::string digits[] = "0123456789abcdef";
//...
const size_t length = str.len;
// Note: iz is the radix for "input" conversion
int number = 0;
for (unsigned int i = 0; i < length; ++i)
{
const std::string::size_type position = digits.find(str[i]);
number = number * iz; // Shift the number by one digit.
number += position;
}
Notice: error handling, such as invalid digits, is left as an exercise for the OP. Invalid digits are not restricted to characters outside the set, but also digits whose index is greater than the conversion radix.
For ultimate understanding, single step through the code with pen and paper. :-)
You can use the table for converting to the target radix, in (I'd rather use a more descriptive variable name).
std::string translated_number;
while (number > 0)
{
const unsigned int index = number % output_radix; // Output_radix == 'in'
const char digit_character = digits[index];
translated_number.insert(0, 1, digit_character);
number = number / output_radix;
}

Trying to print the correct amount of '*' in place of a numeric value

Hey guys so I have a question that is probably pretty simple I just cannot think of a solution. My function void printRanges, correctly checks an arrays values for what its range is and increments the array int ticker[10]. What i want to do is print out the range and how many fall in each category with stars *, instead of the number itself.
So right now I can print it like: "00: 1" and so on, but want to know how i can print out the corresponding amount of stars in place of the number. like: "00: *" "10: **" etc. Do i have to use a bunch of for loops? or is there something really simple I am missing!
Thank you for your help! I really appreciate it!
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
// declare const variable for array size, and array prototypes
const int SIZE = 20;
void fill(int arr[SIZE]);
void print(int arr[SIZE]);
void printRanges(int arr[SIZE]);
int main() {
// create an array with 20 components
int arr[SIZE] = { 0 };
// call functions
fill(arr);
print(arr);
printRanges(arr);
// pause and exit
getchar();
getchar();
return 0;
}
//fills array arr with 20 random numbers
void fill(int arr[SIZE]) {
for (int i = 0; i < SIZE; i++) {
arr[i] = rand() % 100;
}
}
// prints the array
void print(int arr[SIZE]) {
for (int i = 0; i < SIZE; i++) {
cout << arr[i] << " ";
}
}
// finds the range of each value in the array and stores it in the array ticker, then prints
// a list from 00-90 documenting how many values are in each range
void printRanges(int arr[SIZE]) {
int ticker[10] = { 0 };
char star = '*';
for (int i = 0; i < SIZE; i++) {
switch (arr[i] / 10) {
case 0:
ticker[0] = ticker[0] + 1;
break;
case 1:
ticker[1] = ticker[1] + 1;
break;
case 2:
ticker[2] = ticker[2] + 1;
break;
case 3:
ticker[3] = ticker[3] + 1;
break;
case 4:
ticker[4] = ticker[4] + 1;
break;
case 5:
ticker[5] = ticker[5] + 1;
break;
case 6:
ticker[6] = ticker[6] + 1;
break;
case 7:
ticker[7] = ticker[7] + 1;
break;
case 8:
ticker[8] = ticker[8] + 1;
break;
case 9:
ticker[9] = ticker[9] + 1;
break;
}
}
cout << endl << "00: " << star;
}
First, you can eliminate the switch by simplifiying. Then you want a loop to print the ranges.
void printRanges(int arr[SIZE]) {
int ticker[10] = { 0 };
for (int i = 0; i < SIZE; i++) {
unsigned int index = arr[i] / 10;
if (index < 10) {
ticker[index] += 1;
}
}
for (int i = 0; i < 10; i++) {
// Print i pre-padded with "0"
cout << setfill('0') << setw(2) << i << ": ";
// Print the asterisks
cout << setfill('*') << setw(ticker[i]) << "" << endl;
}
}
Don't forget to
#include <iomanip>
for setw and setfill.
DEMO

Stack around variable 'inputValue' corrupted

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!