Program crashes when trying to convert const char* to long long - c++

When the program runs, it crashes at long long thisLong = atoll(c); Is there any reason for this?
string ConvertToBaseTen(long long base4) {
stringstream s;
s << base4;
string tempBase4;
s >> tempBase4;
s.clear();
string tempBase10;
long long total = 0;
for (signed int x = 0; x < tempBase4.length(); x++) {
const char* c = (const char*)tempBase4[x];
long long thisLong = atoll(c);
total += (pow(thisLong, x));
}
s << total;
s >> tempBase10;
return tempBase10;
}

atoll needs const char* as input, but tempBase4[x] only returns char.
If you want to convert each character in string to decimal, try:
for (signed int x = 0; x < tempBase4.length(); x++) {
int value = tempBase4[i] -'0';
total += (pow(value , x));
}
Or if you want to convert the whole tempBase to long long:
long long thisLong = atoll(tempBase4.c_str());
total += (pow(thisLong, x));

Related

Function returns value in hex

I made a function to double every other digit of a number, but for some reason it converts the in to hex before returning. I checked, and that hex is accurate to an actual number, but how do I get it to stop returning hex? Here's the code.
unsigned long long* Luhn_Algorigthem::double_every_other_value(unsigned long long int in) {
unsigned long long int* out = new unsigned long long;
int counter = 10;
for (int i = 0; i < std::to_string(in).length(); i++) {
if (i % 2 == 0) { //Is even
counter * 10;
out += (unsigned long long)((in % counter) * 2);
}
else { //Is odd
out += (unsigned long long)(std::to_string(in).at(i));
}
}
doubled_val = (unsigned long long)out;
return (unsigned long long*)33;
delete out;
}
Unsigned and long are type modifiers (like adjectives without a noun), have you tried unsigned long int for explicit type casting?
#TheUndedFish helped solve the problem for me, I ended up just getting rid of the pointer, and used the doubled val variable for it instead without allocating memory to the heap. This is the updated code:
unsigned long long int Luhn_Algorigthem::double_every_other_value(unsigned long long int in) {
//unsigned long long int* out = new unsigned long long;
int counter = 10;
for (int i = 0; i < std::to_string(in).length(); i++) {
if (i % 2 == 0) { //Is even
counter * 10;
doubled_val += (in % counter) * 2;
}
else { //Is odd
doubled_val += std::to_string(in).at(i);
}
}
//delete out;
return doubled_val;
}

Arduino C/C++ Convert binary string to decimal

I wanted to post this on the Arduino forum but couldn't find any "new post" button...
Anyway, I wrote this function to convert a binary string into an int/long.
However, it doesn't always work with big numbers.
The following code is supposed to return "888888" but returns "888.887"
void setup() {
Serial.begin(9600);
String data = "11011001000000111000"; //888888
Serial.print(binStringToInt(data));
}
unsigned long binStringToInt(String bin) {
unsigned long total = 0;
int binIndex = 0;
for (int i = bin.length() - 1; i > - 1; i--) {
total += round(pow(2, binIndex)) * (bin.charAt(i) - '0');
binIndex++;
}
return total;
}
You can use a simpler function to achieve that:
long binary_to_int(char *binary_string){
long total = 0;
while (*binary_string)
{
total *= 2;
if (*binary_string++ == '1') total += 1;
}
return total;
}
void setup(){
Serial.begin(9600);
String data = "11011001000000111000";
Serial.print(binary_to_int(data.c_str())); // prints 888888
}
I used.c_str() to get a char * to Arduino String.
When programming Arduino rather forget about String and vectors, use C strings and C arrays as it is very resources limited.
Never use floats and float functions when dealing with integers.
unsigned long long convert(const char *str)
{
unsigned long long result = 0;
while(*str)
{
result <<= 1;
result += *str++ == '1' ? 1 : 0;
}
return result;
}

read bits, write bits data to arbitrary position in char array in c++

I created functions to read bit data from arbitrary bit position of char array to long long int, and I also created function to write data to char array from vector bool.
However, I do not really like my implementation since I think it has burden implementations in order to read and write bits.
Can anyone see my implementation and enlighten me for better implementation?
Here is my implementation to write bit data from vector<bool> bitdataForModification
unsigned char*& str is original char array
int startBitLocation is arbitrary bit position to read from
int sizeToModify is the size in bits for modification
void setBitDataToBitPosition(unsigned char*& str, int startBitLocation, int sizeToModify, std::vector<bool>& bitdataForModification){
int endBitLocation = startBitLocation + sizeToModify-1;
int sizeChar = (endBitLocation - startBitLocation)/8;
//Save leftover data
int startCharPosition = startBitLocation/8;
int startLeftOverBits = startBitLocation%8;
//endPosition
int endCharPosition = endBitLocation/8;
int endLeftOverBits = 7-(endBitLocation%8);
unsigned char tempChar = str[startCharPosition];
unsigned char tempLastChar = str[endCharPosition]; // store last char
int posBitdata = 0;
for(int i = 0 ; i < startLeftOverBits; i++){
str[startCharPosition] <<= 1;
str[startCharPosition] = (str[startCharPosition] | ((tempChar >> (7-i)) & 0x1));
}
for(int i = startCharPosition*8 + startLeftOverBits ; i <= endBitLocation ; i++){
str[i/8] <<= 1;
if(posBitdata <= endBitLocation){
str[i/8] = (str[i/8] | ((bitdataForModification[posBitdata]) & 0x1));
posBitdata++;
}
}
for(int i = 0 ; i < endLeftOverBits ; i++){
str[endCharPosition] <<= 1;
str[endCharPosition] = (str[endCharPosition] | ((tempChar >> i) & 0x1));
}
}
I do not like above function because it copies from original char[] to temp char[] and copy back the bits I need.
Following is my read function I implemented.
It reads from char array and copy the data to long long int data
void getBitDataFromBitPosition(unsigned char* str, int startBitLocation, int sizeToRead, unsigned long long* data){
int endBitLocation = startBitLocation + sizeToRead;
int sizeChar = (endBitLocation - startBitLocation)/8;
int startCharPosition = startBitLocation/8;
int endCharPosition = endBitLocation/8 +1;
vector<bool> bitData;
int bitCnt = 0;
for(int i = startCharPosition; i < endCharPosition; i++){
unsigned char tempChar = str[i];
for(int j = 7 ; j >= 0 ; j--){
int curLoc = ((i*8)+(bitCnt%8));
if(curLoc >= startBitLocation){
if(curLoc < endBitLocation){
bool temp = ((str[i] >> j) & 0x1);
bitData.push_back(temp);
}
}
bitCnt++;
}
}
for(int i = bitData.size() -1 ; i >= 0 ; i--){
*data <<= 1;
*data = (*data | bitData[bitData.size()-i-1]);
}
}
I think it is burden to copy to bool vector and copy back to long long int.
Can anyone provide better solution for me?
Thank you in advance!

Converting an array of 2 digit numbers into an integer (C++)

Is it possible to take an array filled with 2 digit numbers e.g.
[10,11,12,13,...]
and multiply each element in the list by 100^(position in the array) and sum the result so that:
mysteryFunction[10,11,12] //The function performs 10*100^0 + 11*100^1 + 12*100^3
= 121110
and also
mysteryFunction[10,11,12,13]
= 13121110
when I do not know the number of elements in the array?
(yes, the reverse of order is intended but not 100% necessary, and just in case you missed it the first time the numbers will always be 2 digits)
Just for a bit of background to the problem: this is to try to improve my attempt at an RSA encryption program, at the moment I am multiplying each member of the array by 100^(the position of the number) written out each time which means that each word which I use to encrypt must be a certain length.
For example to encrypt "ab" I have converted it to an array [10,11] but need to convert it to 1110 before I can put it through the RSA algorithm. I would need to adjust my code for if I then wanted to use a three letter word, again for a four letter word etc. which I'm sure you will agree is not ideal. My code is nothing like industry standard but I am happy to upload it should anyone want to see it (I have also already managed this in Haskell if anyone would like to see that). I thought that the background information was necessary just so that I don't get hundreds of downvotes from people thinking that I'm trying to trick them into doing homework for me. Thank you very much for any help, I really do appreciate it!
EDIT: Thank you for all of the answers! They perfectly answer the question that I asked but I am having problems incorporating them into my current program, if I post my code so far would you be able to help? When I tried to include the answer provided I got an error message (I can't vote up because I don't have enough reputation, sorry that I haven't accepted any answers yet).
#include <iostream>
#include <string>
#include <math.h>
int returnVal (char x)
{
return (int) x;
}
unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
unsigned long long remainder;
int x = 1;
while (e != 0)
{
remainder = e % 2;
e= e/2;
if (remainder == 1)
x = (x * b) % m;
b= (b * b) % m;
}
return x;
}
int main()
{
unsigned long long p = 80001;
unsigned long long q = 70021;
int e = 7;
unsigned long long n = p * q;
std::string foo = "ab";
for (int i = 0; i < foo.length(); i++);
{
std::cout << modExp (returnVal((foo[0]) - 87) + returnVal (foo[1] -87) * 100, e, n);
}
}
If you want to use plain C-style arrays, you will have to separately know the number of entries. With this approach, your mysterious function might be defined like this:
unsigned mysteryFunction(unsigned numbers[], size_t n)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < n; ++i)
{
result += factor * numbers[i];
factor *= 100;
}
return result;
}
You can test this code with the following:
#include <iostream>
int main()
{
unsigned ar[] = {10, 11, 12, 13};
std::cout << mysteryFunction(ar, 4) << "\n";
return 0;
}
On the other hand, if you want to utilize the STL's vector class, you won't separately need the size. The code itself won't need too many changes.
Also note that the built-in integer types cannot handle very large numbers, so you might want to look into an arbitrary precision number library, like GMP.
EDIT: Here's a version of the function which accepts a std::string and uses the characters' ASCII values minus 87 as the numbers:
unsigned mysteryFunction(const std::string& input)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < input.size(); ++i)
{
result += factor * (input[i] - 87);
factor *= 100;
}
return result;
}
The test code becomes:
#include <iostream>
#include <string>
int main()
{
std::string myString = "abcde";
std::cout << mysteryFunction(myString) << "\n";
return 0;
}
The program prints: 1413121110
As benedek mentioned, here's an implementation using dynamic arrays via std::vector.
unsigned mystery(std::vector<unsigned> vect)
{
unsigned result = 0;
unsigned factor = 1;
for (auto& item : vect)
{
result += factor * item;
factor *= 100;
}
return result;
}
void main(void)
{
std::vector<unsigned> ar;
ar.push_back(10);
ar.push_back(11);
ar.push_back(12);
ar.push_back(13);
std::cout << mystery(ar);
}
I would like to suggest the following solutions.
You could use standard algorithm std::accumulate declared in header <numeric>
For example
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s =
std::accumulate( std::begin( a ), std::end( a ), 0ull,
[&]( unsigned long long acc, unsigned int x )
{
return ( acc += x * i, i *= 100, acc );
} );
std::cout << "s = " << s << std::endl;
return 0;
}
The output is
s = 13121110
The same can be done with using the range based for statement
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s = 0;
for ( unsigned int x : a )
{
s += x * i; i *= 100;
}
std::cout << "s = " << s << std::endl;
return 0;
}
You could also write a separate function
unsigned long long mysteryFunction( const unsigned int a[], size_t n )
{
unsigned long long s = 0;
unsigned long long i = 1;
for ( size_t k = 0; k < n; k++ )
{
s += a[k] * i; i *= 100;
}
return s;
}
Also think about using std::string instead of integral numbers to keep an encrypted result.

Convert char array to single int?

Anyone know how to convert a char array to a single int?
char hello[5];
hello = "12345";
int myNumber = convert_char_to_int(hello);
Printf("My number is: %d", myNumber);
There are mulitple ways of converting a string to an int.
Solution 1: Using Legacy C functionality
int main()
{
//char hello[5];
//hello = "12345"; --->This wont compile
char hello[] = "12345";
Printf("My number is: %d", atoi(hello));
return 0;
}
Solution 2: Using lexical_cast(Most Appropriate & simplest)
int x = boost::lexical_cast<int>("12345");
Solution 3: Using C++ Streams
std::string hello("123");
std::stringstream str(hello);
int x;
str >> x;
if (!str)
{
// The conversion failed.
}
If you are using C++11, you should probably use stoi because it can distinguish between an error and parsing "0".
try {
int number = std::stoi("1234abc");
} catch (std::exception const &e) {
// This could not be parsed into a number so an exception is thrown.
// atoi() would return 0, which is less helpful if it could be a valid value.
}
It should be noted that "1234abc" is implicitly converted from a char[] to a std:string before being passed to stoi().
I use :
int convertToInt(char a[1000]){
int i = 0;
int num = 0;
while (a[i] != 0)
{
num = (a[i] - '0') + (num * 10);
i++;
}
return num;;
}
Use sscanf
/* sscanf example */
#include <stdio.h>
int main ()
{
char sentence []="Rudolph is 12 years old";
char str [20];
int i;
sscanf (sentence,"%s %*s %d",str,&i);
printf ("%s -> %d\n",str,i);
return 0;
}
I'll just leave this here for people interested in an implementation with no dependencies.
inline int
stringLength (char *String)
{
int Count = 0;
while (*String ++) ++ Count;
return Count;
}
inline int
stringToInt (char *String)
{
int Integer = 0;
int Length = stringLength(String);
for (int Caret = Length - 1, Digit = 1; Caret >= 0; -- Caret, Digit *= 10)
{
if (String[Caret] == '-') return Integer * -1;
Integer += (String[Caret] - '0') * Digit;
}
return Integer;
}
Works with negative values, but can't handle non-numeric characters mixed in between (should be easy to add though). Integers only.
For example, "mcc" is a char array and "mcc_int" is the integer you want to get.
char mcc[] = "1234";
int mcc_int;
sscanf(mcc, "%d", &mcc_int);
With cstring and cmath:
int charsToInt (char* chars) {
int res{ 0 };
int len = strlen(chars);
bool sig = *chars == '-';
if (sig) {
chars++;
len--;
}
for (int i{ 0 }; i < len; i++) {
int dig = *(chars + i) - '0';
res += dig * (pow(10, len - i - 1));
}
res *= sig ? -1 : 1;
return res;
}
Ascii string to integer conversion is done by the atoi() function.
Long story short you have to use atoi()
ed:
If you are interested in doing this the right way :
char szNos[] = "12345";
char *pNext;
long output;
output = strtol (szNos, &pNext, 10); // input, ptr to next char in szNos (null here), base