0

I have a very long number with hundreds of digits which I have stored in a string. Now, I want to read it into an integer/long digit-by-digit.

long int strtol ( const char * str, char ** endptr, int base ); takes an end-pointer, but it doesn't seem like I can set it right, because it tries to read in all digits, and hence, returns LONG_MAX.

char str[]=
"70172427121883998797908792274921901699720888093776\
65727333001053367881220235421809751254540594752243\
52584907711670556013604839586446706324415722155397\
53697817977846174064955149290862569321978468622482\
83972241375657056057490261407972968652414535100474\
82166370484403199890008895243450658541227588666881\
16427171479924442928230863465674813919123162824586";

char *pEnd; //set pEnd to str[1]'s address how???
long num = strtol(str, &pEnd,  10);
cout << num << endl; //LONG_MAX

I thought of solutions like copying it to a new character array, and then applying strtol but that doesn't seem like the best way to do it.

So what would be the easiest/best way to do this?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191

5 Answers5

6

If you want to read a single digit, you can simply use:

int digit = str[digitIndex] - '0';

This works, regardless of the character set used by the implementation, because the standard guarantees that the digits '0'-'9' will be represented by contiguous values.

The endptr parameter of strtol doesn't do what you think: It is used to return the position where the conversion stopped, not to tell the function where to stop.

If you want to convert a multi-digit substring of str, you can copy the required digits only to a new string, like this:

std::string partialStr(str+startIndex, numDigits);

and then convert it to an integer using one of the methods here.

Community
  • 1
  • 1
interjay
  • 107,303
  • 21
  • 270
  • 254
4

converting a single digit to its int representation is easy, you'd e.g. do

int i = str[0] - '0'; 

For the first digit. So you just need to create an array of integer, iterate over the string and convert each digit, storing the result in the array of ints.

nos
  • 223,662
  • 58
  • 417
  • 506
1

The end pointer is an output from that strtol. It tells you where it stopped reading, not the other way around.

If you want to read an individual digit then just do this:

digit = str[0] - '0';
ams
  • 24,923
  • 4
  • 54
  • 75
1

If the base is 10, and LENGTH is the string Length, do:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/*Prototype*/
long int intpow( int base, int exp);

int main(void)
{
    long int result = 0;
    int i, j = 0;
    char str[] = /* blah blah*/

    for( i = LENGHT - 1; i >= 0; i--){
        /* -48 because ASCII code. */
        result +=  ( str[ i ] - 48 ) * intpow( 10, j );
        j++;
    }
}

/* Recursive integer power function*/
long int intpow( int base, int exp)
{
    if( exp == 0)
      return 1;

    else
      return base * intpow( base, exp - 1);
}
Alberto Bonsanto
  • 17,556
  • 10
  • 64
  • 93
1

use std::transform if you want to convert not only one of the digits but all of them:

size_t N = sizeof(str) -1 ; //or strlen(str) if str is a pointer, not an array
std::vector<int> theInts(N); 
std::transform(str, str+N, begin(theInts), [](char* pc){ return *pc -'0'; });
Arne Mertz
  • 24,171
  • 3
  • 51
  • 90
  • The code isn't correct. **1.** it should be `str.size()`, not `sizeof(str)`, **2.** that `function` doesn't look right. But `std::transform` does have potential for converting multiple values, hence, +1. – Anirudh Ramanathan Nov 28 '12 at 14:29
  • **1.** In the original post it says `char str[] = "345335"` etc., so `str` is not a `std::string` but an array of chars that has no method `size()`. `sizeof(str)` will give the size of that array in bytes including the zero-delimiter, so I'll correct the code (`-1`). **2.** which `function` do you mean? If it's the fourth argument to `std::transform` that looks "not right" to you: it is a C++11 lambda, taking one parameter and returning a char. – Arne Mertz Nov 29 '12 at 08:42