Stack around variable 'inputValue' corrupted - c++

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!

Related

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

Using Array as parameter in function in 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);
...
}

How to rearrange a string equation?

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.

convert int to char without itoa() [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
i have a program and i should convert int to char into it
but i cant use itoa() because site's judge don't support it
so i wrote this:
xt[i]= rmn+'0';
but i get this error :
Runtime error: Illegal file open (/dev/tty)
How should i convert this?
My code is this : (for palsquare question of USACO)
/*
ID: sa.13781
PROG: palsquare
LANG: C++
*/
#include <iostream>
#include <fstream>
using namespace std;
ofstream fout("palsquare.out");
int tool(char xt[])//CORRECT
{
int p = 0;
while (xt[p] != 0)
p++;
return p;
}
void prt(char xt[])//CORRECT
{
int p = 0;
while (xt[p] != 0)
{
fout << xt[p];
p++;
}
}
void mabna(int a, char xt[], int mab)
{
int ex = 1, tavan = 0, rmn, n;
for (; ex <= a; ex *= mab)
tavan++;
for (int i = tavan - 1; a != 0; i--, a /= mab)
{
rmn = a % mab;
switch (rmn)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
xt[i] = rmn + '0';
break;
case 10:
xt[i] = 'A';
break;
case 11:
xt[i] = 'B';
break;
case 12:
xt[i] = 'C';
break;
case 13:
xt[i] = 'D';
break;
case 14:
xt[i] = 'E';
break;
case 15:
xt[i] = 'F';
break;
case 16:
xt[i] = 'G';
break;
case 17:
xt[i] = 'H';
break;
case 18:
xt[i] = 'I';
break;
case 19:
xt[i] = 'J';
break;
}
}
}
bool mirror(char *xt)//CORRECT
{
int p = 0;
int n = tool(xt);
for (int i = 0; i < (n / 2); i++)
if (xt[i] == xt[n - i - 1])
p++;
if (p == (n / 2))
return true;
return false;
}
void calc(int mab) //CORRECT
{
for (int i = 1; i <= 300; i++)
{
char p[10] = {0}, p2[10] = {0};
mabna(i * i, p2, mab);
if ( mirror(p2) == true )
{
mabna(i, p, mab);
prt(p);
fout << " ";
prt(p2);
fout << "\n";
}
}
}
int main()
{
ifstream fin("palsquare.in");
int mab;
fin >> mab;
calc(mab);
return 0;
}
Can you use sprintf()?
char s[16];
int x = 15;
sprintf(s, "%d", x);
If your int value is single digit, you can just cast it with (char)
If your int value is more than one digit, you can never expect a single char to hold it. char can only hold single character.
int num = 7;
char ch = (num + 48); //same effect as + '0'
cout << ch << endl;
OUTPUT: 7
If your int value is more than single digit. You need char* or char[] to hold the converted data. For example:
int num = 123987;
int len = 6;
int idx = len-1;;
char ch[20];
while(num > 0)
{
ch[idx] = (num%10) + 48;
num /= 10;
idx --;
}
for(int x=0; x<len; x++)
cout << "OUTPUT in char: " << ch[x];
OUTPUT in char: 123987
This is not a perfectly good way to handle this kind of situation, but it may gives you what you asked for.