Change 'parameter' string inside method C++ - c++

it is my first question in SO, but I cannot find a good solution for this, not online nor from my brain.
I have a big string of number (over 100 digits) and I need to remove some of its digits to create a number divisible by 8. It is really simple...
However, lets say the only way to create this number is with a number that ends with '2'. In this case I would need to look for proper 10's and 100's digits and it is at this point I cannot find an elegant solution.
I have this:
bool ExistDigit(string & currentNumber, int look1) {
int currentDigit;
int length = currentNumber.length();
for (int i = length - 1; i >= 0; i--) {
currentDigit = -48;//0 in ASC II
currentDigit += currentNumber.back();//sum ASCII's value of char to current Digit
if (currentDigit == look1) {
return true;
}
else
currentNumber.pop_back;
}
return false;
}
It modify the string but since I check for 8's and 0's first, by the time I get to check 2's, the string is empty already. I solved this by creating several copies of the string, but I would like to know if there is a better way and what is it.
I know that if I use ExistDigit(string CurrentNumber, int look1), the string does not get modified, but in this case, it would not help with the 2, because after finding the two I need to look for 1's, 5's and 9's after the 2 in the original string.
What is the correct approach to these kind of problems? I mean, should I stick with changing the string or should I return a value for the position of the 2 (for example) and work from there? If it is good to change the string, how should I do it in order to be able to reuse the original string?
I am new to C++, and coding in general (just started actually) so, sorry if it is a really silly question. Thanks in advance.
EDIT: My call look like this:
int main() {
string originalNumber;//hold number. Must be string because number can be too long for ints
cin >> originalNumber;
string answer = "YES";
string strNumber;
//look for 0's and 8's. they are solutions by their own
strNumber = originalNumber;
if (ExistDigit(strNumber, 0)) {
answer += "\n0";
}
else {
strNumber = originalNumber;
if (ExistDigit(strNumber, 8)) {
answer += "\n8";
}
else {
strNumber = originalNumber;
//look for 'even'32, 'even'72, 'odd'12, 'odd'52, 'odd'92
//these are the possibilities for multiples of 8 ended with 2
if (ExistDigit(strNumber, 2)) {
if (ExistDigit(strNumber, 1)) {
}
}
else {
EDIT 2: In case you have the same problem, check the function find_last_of, it is really convenient and solves the problem.

The following code retains your design and should give at least a solution if one exists. The nested if and for can be simplified within a more elegant solution by using a recursive function. With such a recursive function, you could also enumerate all the solutions.
Instead of having multiple copies of the string, you could use an iterator that defines the start of the search. In the code the start variable is this iterator.
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
bool ExistDigit(const string & currentNumber, int& start, int look1) {
int currentDigit;
int length = currentNumber.length();
for (int i = length - 1 - start; i >= 0; i--) {
currentDigit = currentNumber[i] - '0';
if (currentDigit == look1) {
start = length - i;
return true;
}
}
return false;
}
int main() {
string originalNumber;//hold number. Must be string because number can be too long for ints
cin >> originalNumber;
stringstream answer;
answer << "YES";
//look for 0's and 8's. they are solutions by their own
int start = 0;
if (ExistDigit(originalNumber, start, 0)) {
answer << "\n0";
}
else {
start = 0;
if (ExistDigit(originalNumber, start, 8)) {
answer << "\n8";
}
else {
start = 0;
//look for 'even'32, 'even'72, 'odd'12, 'odd'52, 'odd'92
//these are the possibilities for multiples of 8 ended with 2
if (ExistDigit(originalNumber, start, 2)) {
for (int look2 = 1; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) { // 'odd'
for (int look3 = 1; look3 < 10; look3 += 2) {
int startAttempt2 = startAttempt1;
if (ExistDigit(originalNumber, startAttempt2, look3))
answer << "\n" << look3 << look2 << "2";
};
}
};
for (int look2 = 3; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) // 'even'
answer << "\n" << look2 << "2";
};
}
//look for 'odd'36, 'odd'76, 'even'12, 'even'52, 'even'92
//these are the possibilities for multiples of 8 ended with 2
else if (ExistDigit(originalNumber, start, 6)) {
for (int look2 = 3; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) { // 'odd'
for (int look3 = 1; look3 < 10; look3 += 2) {
int startAttempt2 = startAttempt1;
if (ExistDigit(originalNumber, startAttempt2, look3))
answer << "\n" << look3 << look2 << "6";
};
}
};
for (int look2 = 1; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) // 'even'
answer << "\n" << look2 << "6";
};
}
//look for 'even'24, 'even'64, 'odd'44, 'odd'84, 'odd'04
//these are the possibilities for multiples of 8 ended with 2
else if (ExistDigit(originalNumber, start, 6)) {
for (int look2 = 0; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) { // 'odd'
for (int look3 = 1; look3 < 10; look3 += 2) {
int startAttempt2 = startAttempt1;
if (ExistDigit(originalNumber, startAttempt2, look3))
answer << "\n" << look3 << look2 << "4";
};
}
};
for (int look2 = 2; look2 < 10; look2 += 4) {
int startAttempt1 = start;
if (ExistDigit(originalNumber, startAttempt1, look2)) // 'even'
answer << "\n" << look2 << "4";
};
}
}
}
cout << answer.str() << std::endl;
return 0;
}
Here is a solution when you are looking for a subword composed of successive characters in the decimal textual form.
#include <string>
#include <iostream>
bool ExistDigit(const std::string& number, int look) { // look1 = 2**look
// look for a subword of size look that is divisible by 2**look = 1UL << look
for (int i = (int) number.size()-1; i >= 0; --i) {
bool hasFound = false;
unsigned long val = 0;
int shift = look-1;
if (i-shift <= 0)
shift = i;
for (; shift >= 0; --shift) {
val *= 10;
val += (number[i-shift] - '0');
};
if (val % (1UL << look) == 0)
return true;
};
return false;
}
int main(int argc, char** argv) {
std::string val;
std::cin >> val;
if (ExistsDigit(val, 3) /* since 8 = 2**3 = (1 << 3) */)
std::cout << "have found a decimal subword divisible by 8" << std::endl;
else
std::cout << "have not found any decimal subword divisible by 8" << std::endl;
return 0;
}
If you are likely to find a subword of consecutive bits in the binary form of the number, you need to convert your number in a big integer and then to do similar search.
Here is a (minimal-tested) solution without any call to an external library like gmp to convert the text in a big integer. This solution makes use of bitwise operations (<<, &).
#include <iostream>
#include <string>
#include <vector>
int
ExistDigit(const std::string & currentNumber, int look) { // look1 = 2^look
std::vector<unsigned> bigNumber;
int length = currentNumber.size();
for (int i = 0; i < length; ++i) {
unsigned carry = currentNumber[i] - '0';
// bigNumber = bigNumber * 10 + carry;
for (int index = 0; index < bigNumber.size(); ++index) {
unsigned lowPart = bigNumber[index] & ~(~0U << (sizeof(unsigned)*4));
unsigned highPart = bigNumber[index] >> (sizeof(unsigned)*4);
lowPart *= 10;
lowPart += carry;
carry = lowPart >> (sizeof(unsigned)*4);
lowPart &= ~(~0U << (sizeof(unsigned)*4));
highPart *= 10;
highPart += carry;
carry = highPart >> (sizeof(unsigned)*4);
highPart &= ~(~0U << (sizeof(unsigned)*4));
bigNumber[index] = lowPart | (highPart << (sizeof(unsigned)*4));
}
if (carry)
bigNumber.push_back(carry);
};
// here bigNumber should be a biginteger = currentNumber
for (int i = 0; i < bigNumber.size()*8*sizeof(unsigned); ++i) {
// looks for look consective bits set to '0'
bool hasFound = true;
for (int shift = 0; hasFound && shift < look; ++shift)
if (bigNumber[(i+shift) / (8*sizeof(unsigned))]
& (1U << ((i+shift) % (8*sizeof(unsigned)))) != 0)
hasFound = false;
if (hasFound) { // ok, bigNumber has look consecutive bits set to 0
// test if we are at the end of the bigNumber
int index = (i+look) / (8*sizeof(unsigned));
for (int j = ((i+look+8*sizeof(unsigned)-1) % (8*sizeof(unsigned)))+1;
j < (8*sizeof(unsigned)); j++)
if ((bigNumber[index] & (1U << j)) != 0)
return i; // the result is (currentNumber / (2^i));
while (++index < bigNumber.size())
if (bigNumber[index] != 0)
return i; // the result is (currentNumber / (2^i));
return -1;
};
};
return -1;
}
int main(int argc, char** argv) {
std::string val;
std::cin >> val;
std::cout << val << " is divided by 8 after " << ExistDigit(val, 3) << " bits." << std::endl;
return 0;
}

Related

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

Strange behaviour of pointers in C++

#include <cstdlib>
#include <iostream>
#include <Math.h>
#include <algorithm>
#include <string>
#include <iterator>
#include <iostream>
#include <vector> // std::vector
using namespace std;
int stepCount, i, x, y, z, j, k, array1Size, array2Size, tester, checker;
int numstring[10] = { 0,1,2,3,4,5,6,7,8,9 };
int numstringTest[10] = { 0,1,2,3,4,5,6,7,7,9 };
int* numbers;
int* differentNumbers;
int* p;
int* otherNumbers;
void stepCounter(int a) {
// determines the step number of the number
if (a / 10 == 0)
stepCount = 1;
else if (a / 100 == 0)
stepCount = 2;
else if (a / 1000 == 0)
stepCount = 3;
else if (a / 10000 == 0)
stepCount = 4;
else if (a / 100000 == 0)
stepCount = 5;
else if (a / 1000000 == 0)
stepCount = 6;
else if (a / 10000000 == 0)
stepCount = 7;
else if (a / 100000000 == 0)
stepCount = 8;
else if (a / 1000000000 == 0)
stepCount = 9;
}
void stepIndicator(int b) {
// indicates each step of the number and pass them into array 'number'
stepCounter(b);
numbers = new int[stepCount];
for (i = stepCount; i>0; i--) {
//
/*
x = (round(pow(10,stepCount+1-i)));
y = (round(pow(10,stepCount-i)));
z = (round(pow(10,stepCount-i)));
*/
x = (int)(pow(10, stepCount + 1 - i) + 0.5);
y = (int)(pow(10, stepCount - i) + 0.5);
numbers[i - 1] = (b%x - b%y) / y;
}
}
int sameNumberCheck(int *array, int arraySize) {
//checks if the array has two or more of same integer inside return 1 if same numbers exist, 0 if not
for (i = 0; i<arraySize - 1; i++) {
//
for (j = i + 1; j<arraySize; j++) {
//
if (array[i] == array[j]) {
//
return 1;
}
}
}
return 0;
}
void getDifferentNumbers(int* array, int arraySize) {
//
k = 0;
j = 0;
checker = 0;
otherNumbers = new int[10 - arraySize]; //exact number of other numbers is 10 - numbers we have
for (i = 0; i<10; i++) {
if ((i>0)&(checker = 0)) {
k++;
otherNumbers[k - 1] = i - 1;
}
//
checker = 0;
for (j = 0; j<arraySize; j++) {
//
p = array + j;
cout << *p << endl; //ilkinde doğru sonra yanlış yapıyor?!
if (*p = i) {
checker++;
}
}
}
}
int main(int argc, char *argv[])
{
stepCounter(999999);
cout << stepCount << endl;
stepIndicator(826424563);
for (j = 0; j<9; j++) {
//
cout << numbers[j] << endl;
}
cout << sameNumberCheck(numstringTest, 10) << " must be 1" << endl;
cout << sameNumberCheck(numstring, 10) << " must be 0" << endl;
cout << endl;
getDifferentNumbers(numstringTest, 10);
cout << endl;
cout << endl << otherNumbers[0] << " is the diff number" << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Hi, my problem is with pointers actually. You will see above, function getDifferentNumbers. It simply does a comparement if in any given array there are repeated numbers(0-9). To do that, I passed a pointer to the function. I simply do the comparement via pointer. However, there is a strange thing here. When I execute, first time it does correct, but secon time it goes completely mad! This is the function:
void getDifferentNumbers(int* array, int arraySize) {
//
k = 0;
j = 0;
checker = 0;
otherNumbers = new int[10 - arraySize]; //exact number of other numbers is 10 - numbers we have
for (i = 0; i<10; i++) {
if ((i>0)&(checker = 0)) {
k++;
otherNumbers[k - 1] = i - 1;
}
//
checker = 0;
for (j = 0; j<arraySize; j++) {
//
p = array + j;
cout << *p << endl; //ilkinde doğru sonra yanlış yapıyor?!
if (*p = i) {
checker++;
}
}
}
}
and this is the array I passed into the function:
int numstringTest[10] = {0,1,2,3,4,5,6,7,7,9};
it should give the number 7 in otherNumbers[0], however it does not. And I do not know why. I really can not see any wrong statement or operation here. When I execute, it first outputs the correct values of
numstringTest: 1,2,3,4,5,6,7,7,9
but on next 9 iteration of for loop it outputs:
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888
You have some basic problems in your code.
There are multiple comparisons that are not really comparisons, they're assignments. See the following:
if((i>0) & (checker=0)){
and
if(*p = i){
In both cases you're assigning values to the variables, not comparing them. An equality comparison should use ==, not a single =. Example:
if (checker == 0) {
Besides that, you're using & (bitwise AND) instead of && (logical AND), which are completely different things. You most likely want && in your if statement.
I've just noticed this:
getDifferentNumbers(numstringTest, 10);
and in that function:
otherNumbers = new int[10 - arraySize];
which doesn't seem right.

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.**

Optimizing conversion algorithm

I have recently been working on a exercise in a book I have been reading. The task was to create a program that prints all the numbers between 1-256 in their binary, octal and hexadecimal equivalents. We were only supposed to use methods we had learned so far in the book, which meant only using for, while and do..while loops, if and else if statements, converting integers to ASCII equivalents and some more basic stuff (e.g. cmath and iomanip).
So after some work, here is my result. However, it is messy and un-elegant and obfuscated. Does anyone have any suggestions to increase code efficiency (or elegance... :P) and performance?
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main()
{
int decimalValue, binaryValue, octalValue, hexadecimalValue, numberOfDigits;
cout << "Decimal\t\tBinary\t\tOctal\t\tHexadecimal\n\n";
for (int i = 1; i <= 256; i++)
{
binaryValue = 0;
octalValue = 0;
hexadecimalValue = 0;
if (i != 0)
{
int x, j, e, c, r = i, tempBinary, powOfTwo, tempOctal, tempDecimal;
for (j = 0; j <=8; j++) //Starts to convert to binary equivalent
{
x = pow(2.0, j);
if (x == i)
{
powOfTwo = 1;
binaryValue = pow(10.0, j);
break;
}
else if (x > i)
{
powOfTwo = 0;
x /= 2;
break;
}
}
if (powOfTwo == 0)
{
for (int k = j-1; k >= 0; k--)
{
if ((r-x)>=0)
{
r -= x;
tempBinary = pow(10.0, k);
x /= 2;
}
else if ((r-x)<0)
{
tempBinary = 0;
x /= 2;
}
binaryValue += tempBinary;
}
} //Finished converting
int counter = ceil(log10(binaryValue+1)); //Starts on octal equivalent
int iter;
if (counter%3 == 0)
{
iter = counter/3;
}
else if (counter%3 != 0)
{
iter = (counter/3)+1;
}
c = binaryValue;
for (int h = 0; h < iter; h++)
{
tempOctal = c%1000;
int count = ceil(log10(tempOctal+1));
tempDecimal = 0;
for (int counterr = 0; counterr < count; counterr++)
{
if (tempOctal%10 != 0)
{
e = pow(2.0, counterr);
tempDecimal += e;
}
tempOctal /= 10;
}
octalValue += (tempDecimal * pow(10.0, h));
c /= 1000;
}//Finished Octal conversion
cout << i << "\t\t" << binaryValue << setw(21-counter) << octalValue << "\t\t";
int c1, tempHex, tempDecimal1, e1, powOf;
char letter;
if (counter%4 == 0)//Hexadecimal equivalent
{
iter = counter/4;
}
else if (counter%4 != 0)
{
iter = (counter/4)+1;
}
c1 = binaryValue;
for (int h = 0, g = iter-1; h < iter; h++, g--)
{
powOf = g*4;
if (h == 0)
{
tempHex = c1 / pow(10.0, powOf);
}
else if (h > 0)
{
tempHex = c1 / pow(10.0, powOf);
tempHex %= 10000;
}
int count = ceil(log10(tempHex+1));
tempDecimal1 = 0;
for (int counterr = 0; counterr < count; counterr++)
{
if (tempHex%10 != 0)
{
e1 = pow(2.0, counterr);
tempDecimal1 += e1;
}
tempHex /= 10;
}
if (tempDecimal1 <= 9)
{
cout << tempDecimal1;
}
else if (tempDecimal1 > 9)
{
cout << char(tempDecimal1+55); //ASCII's numerical value for A is 65. Since 10-15 are supposed to be letters you just add 55
}
}
cout << endl;
}
}
system("pause");
return 0;
}
Any recommendations for improvement will be appreciated.
You have already covered 'iomanip', which infers you've already covered 'iostream'.
If that's the case, have a look at the following:
#include <iostream>
#include <iomanip>
using namespace std;
int x = 250;
cout << dec << x << " "
<< oct << x << " "
<< hex << x << "\n"
<< x << "\n"; // This will still be in HEX
Break out the functions for each output type, then loop through the integer list and output each in turn by calling the function for each different format.
for (int i = 1; i <= 256; ++i)
{
printBin(i);
printHex(i);
printOct(i);
}
Fundamental problem is that a function this long needs refactoring to be more modular. Imagine you are writing the code for someone else to use. How can they call your main? How do they understand what each section of code is doing? They can't. If you make each section of code that has a particular job to do callable as a function then it's easier to understand its intent, and to reuse later.
Have you considered writing a general function that works with any base?
Converting a non-negative number to a generic base is simple... you just need to compute number % base and you get the least significant digit, then divide number by base and repeat to get other digits...
std::string converted_number;
do {
int digit = number % base;
converted_number = digits[digit] + converted_number;
number = number / base;
} while (number != 0);
Once you have a generic conversion function then solving your problem is easy... just call it with base=2, 8 and 16 to get the results you need as strings.
My answer may be a bit tongue in cheek, but
printf ("%u %o %x \n", value, value, value);
will do the trick for the octal and hexadecimal versions ;)
For the binary version, i'd use a flag initialized to 256, and compare it to your number with the AND operator. If true, print a 1, if not, print a 0. Then divide the flag by two. Repeat until the flag is 1.
Pseudocode for the conversion from integer to binary
int flag = 256
do
{
if (flag && value)
print "1"
else
print "0"
flag = flag >> 1 // aka divide by two, if my memory serves well
} while flag > 1
For the octal and hex values, i'm a bit rusty but looking around should guide you to samples you may adapt
Why make it any harder than it really is.
for (int i = 1; i <= 256; ++i)
{
std::cout << std::dec << i << "\t" << std::oct << i << "\t" << std::hex << i << std::endl;
}
Try this
using namespace std;
template <typename T>
inline void ShiftMask(T& mask) {
mask = (mask >> 1) & ~mask;
}
template < typename T >
std::ostream& bin(T& value, std::ostream &o)
{
T mask = 1 << (sizeof(T) * 8 - 1);
while (!(value & mask) && (mask != 0)) ShiftMask(mask);
while (mask) {
o << (value & mask ? '1' : '0');
ShiftMask(mask);
}
return o;
}
int main(void) {
for (int i=0; i<256;i++) {
bin(a, std::cout);
cout << " " << oct << i;
cout << " " << dec << i;
cout << " " << hex << i;
cout << ""
}
}
Maybe something like this?
#include "stdio.h"
int main(){
char Chars[16]= {48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70};
for(int n = 1;n != 256; n++)
{
{//decimal
printf("%i\t", n);
}
{//Hexadecimal
char L, R;
R = (n & 0x0F) >> 0;
L = (n & 0xF0) >> 4;
printf("%c%c\t", Chars[L], Chars[R]);
}
{//Octal
char L, M, R;
R = (n & 0x07) >> 0;
M = (n & 0x38) >> 3;
L = (n & 0xC0) >> 6;
printf("%c%c%c\t", Chars[L], Chars[M], Chars[R]);
}
{//Binary
char B0, B1, B2, B3, B4, B5, B6, B7;
B0 = (n & 0x01) >> 0;
B1 = (n & 0x02) >> 1;
B2 = (n & 0x04) >> 2;
B3 = (n & 0x08) >> 3;
B4 = (n & 0x10) >> 4;
B5 = (n & 0x20) >> 5;
B6 = (n & 0x40) >> 6;
B7 = (n & 0x80) >> 7;
printf("%c%c%c%c%c%c%c%c\n", Chars[B0], Chars[B1], Chars[B2], Chars[B3], Chars[B4], Chars[B5], Chars[B6], Chars[B7]);
}
printf("256\t100\t400\t100000000\n");
}
}

C++ get each digit in int

I have an integer:
int iNums = 12476;
And now I want to get each digit from iNums as integer. Something like:
foreach(iNum in iNums){
printf("%i-", iNum);
}
So the output would be: "1-2-4-7-6-".
But i actually need each digit as int not as char.
Thanks for help.
void print_each_digit(int x)
{
if(x >= 10)
print_each_digit(x / 10);
int digit = x % 10;
std::cout << digit << '\n';
}
Convert it to string, then iterate over the characters. For the conversion you may use std::ostringstream, e.g.:
int iNums = 12476;
std::ostringstream os;
os << iNums;
std::string digits = os.str();
Btw the generally used term (for what you call "number") is "digit" - please use it, as it makes the title of your post much more understandable :-)
Here is a more generic though recursive solution that yields a vector of digits:
void collect_digits(std::vector<int>& digits, unsigned long num) {
if (num > 9) {
collect_digits(digits, num / 10);
}
digits.push_back(num % 10);
}
Being that there are is a relatively small number of digits, the recursion is neatly bounded.
Here is the way to perform this action, but by this you will get in reverse order.
int num;
short temp = 0;
cin>>num;
while(num!=0){
temp = num%10;
//here you will get its element one by one but in reverse order
//you can perform your action here.
num /= 10;
}
I don't test it just write what is in my head. excuse for any syntax error
Here is online ideone demo
vector <int> v;
int i = ....
while(i != 0 ){
cout << i%10 << " - "; // reverse order
v.push_back(i%10);
i = i/10;
}
cout << endl;
for(int i=v.size()-1; i>=0; i--){
cout << v[i] << " - "; // linear
}
To get digit at "pos" position (starting at position 1 as Least Significant Digit (LSD)):
digit = (int)(number/pow(10,(pos-1))) % 10;
Example: number = 57820 --> pos = 4 --> digit = 7
To sequentially get digits:
int num_digits = floor( log10(abs(number?number:1)) + 1 );
for(; num_digits; num_digits--, number/=10) {
std::cout << number % 10 << " ";
}
Example: number = 57820 --> output: 0 2 8 7 5
You can do it with this function:
void printDigits(int number) {
if (number < 0) { // Handling negative number
printf('-');
number *= -1;
}
if (number == 0) { // Handling zero
printf('0');
}
while (number > 0) { // Printing the number
printf("%d-", number % 10);
number /= 10;
}
}
Drawn from D.Shawley's answer, can go a bit further to completely answer by outputing the result:
void stream_digits(std::ostream& output, int num, const std::string& delimiter = "")
{
if (num) {
stream_digits(output, num/10, delimiter);
output << static_cast<char>('0' + (num % 10)) << delimiter;
}
}
void splitDigits()
{
int num = 12476;
stream_digits(std::cout, num, "-");
std::cout << std::endl;
}
I don't know if this is faster or slower or worthless, but this would be an alternative:
int iNums = 12476;
string numString;
stringstream ss;
ss << iNums;
numString = ss.str();
for (int i = 0; i < numString.length(); i++) {
int myInt = static_cast<int>(numString[i] - '0'); // '0' = 48
printf("%i-", myInt);
}
I point this out as iNums alludes to possibly being user input, and if the user input was a string in the first place you wouldn't need to go through the hassle of converting the int to a string.
(to_string could be used in c++11)
I know this is an old post, but all of these answers were unacceptable to me, so I wrote my own!
My purpose was for rendering a number to a screen, hence the function names.
void RenderNumber(int to_print)
{
if (to_print < 0)
{
RenderMinusSign()
RenderNumber(-to_print);
}
else
{
int digits = 1; // Assume if 0 is entered we want to print 0 (i.e. minimum of 1 digit)
int max = 10;
while (to_print >= max) // find how many digits the number is
{
max *= 10;
digits ++;
}
for (int i = 0; i < digits; i++) // loop through each digit
{
max /= 10;
int num = to_print / max; // isolate first digit
to_print -= num * max; // subtract first digit from number
RenderDigit(num);
}
}
}
Based on #Abyx's answer, but uses div so that only 1 division is done per digit.
#include <cstdlib>
#include <iostream>
void print_each_digit(int x)
{
div_t q = div(x, 10);
if (q.quot)
print_each_digit(q.quot);
std::cout << q.rem << '-';
}
int main()
{
print_each_digit(12476);
std::cout << std::endl;
return 0;
}
Output:
1-2-4-7-6-
N.B. Only works for non-negative ints.
My solution:
void getSumDigits(int n) {
std::vector<int> int_to_vec;
while(n>0)
{
int_to_vec.push_back(n%10);
n=n/10;
}
int sum;
for(int i=0;i<int_to_vec.size();i++)
{
sum+=int_to_vec.at(i);
}
std::cout << sum << ' ';
}
The answer I've used is this simple function:
int getDigit(int n, int position) {
return (n%(int)pow(10, position) - (n % (int)pow(10, position-1))) / (int)pow(10, position-1);
}
Hope someone finds this helpful!
// Online C++ compiler to run C++ program online
#include <iostream>
#include <cmath>
int main() {
int iNums = 123458;
// int iNumsSize = 5;
int iNumsSize = trunc(log10(iNums)) + 1; // Find length of int value
for (int i=iNumsSize-1; i>=0; i--) {
int y = pow(10, i);
// The pow() function returns the result of the first argument raised to
the power of the second argument.
int z = iNums/y;
int x2 = iNums / (y * 10);
printf("%d ",z - x2*10 ); // Print Values
}
return 0;
}
You can do it using a while loop and the modulo operators.
It just gives the digits in the revese order.
int main() {
int iNums = 12476;
int iNum = 0;
while(iNums > 0) {
iNum = iNums % 10;
cout << iNum;
iNums = iNums / 10;
}
}
int a;
cout << "Enter a number: ";
cin >> a;
while (a > 0) {
cout << a % 10 << endl;
a = a / 10;
}
int iNums = 12345;
int iNumsSize = 5;
for (int i=iNumsSize-1; i>=0; i--) {
int y = pow(10, i);
int z = iNums/y;
int x2 = iNums / (y * 10);
printf("%d-",z - x2*10 );
}