1

I have a long array of ints that need to be converted to string. The array is about 1000 - 10000 ints long and value of all of those ints is between 0-9. Is there any fast and effective STANDARD way to convert whole int array to string? It really has to be done only using standard libraries. Thanks.

Jav_Rock
  • 22,059
  • 20
  • 123
  • 164
user1145902
  • 187
  • 1
  • 2
  • 7

4 Answers4

7

Old C++:

std::string s; s.reserve(arr_len);
std::transform(arr, arr+arr_len, std::back_inserter(s),
               std::bind1st(std::plus<int>(), '0'));

C++11:

 std::transform(arr, arr+arr_len, std::back_inserter(s),
               [](int c){return c+'0';});

Not that 1+'0' is not necessarily '1', but in practice you can safely assume so.

ipc
  • 8,045
  • 29
  • 33
  • 2
    The standard guarantees that the ten decimal digits are in sequential ascending order, so `1 + '0'` is guaranteed to be `'1'`. (This is about the only guarantee it gives concerning encoding---in particular `1 + 'a'` is not guaranteed to be `'b'`. Or even a letter.) – James Kanze Jan 31 '12 at 15:29
  • thanks, but these functions aren't included in standard libraries, are they? – user1145902 Jan 31 '12 at 15:32
  • Yes, they are. You have to include `` and `` to take use of them. – ipc Jan 31 '12 at 15:35
6

std::string or C string?

Anyway for one character, the conversion is: char c = array[i]+'0';

Extended that over entire array and you are done.

Šimon Tóth
  • 35,456
  • 20
  • 106
  • 151
  • thanks, i didnt think that it will be that simple. It's very fast too, whole conversion (300 ints) ends in less than 1 sec. – user1145902 Jan 31 '12 at 15:30
1

It depends largely on the semantics of those ints. If they're descrete values (say the results of throwing 1000&ndahs;10000 ten sided dice), then something like:

std::ostream&
operator<<( std::ostream& dest, std::vector<int> const& source )
{
    dest << '[';
    for ( std::vector<int>::const_iterator current = source.begin();
            current != source.end();
            ++ current ) {
        if ( current != source.begin() ) {
            dest << ", ";
        }
        dest << *current;
    }
    dest << ']';
    return dest;
}

might do the trick; more likely, you'd want to pick up dest.width(), and set it before the output of each int (or treat it as the total width, and work out how much padding you need per int, and set that before outputting each int), and you also might want to insert line breaks.

If, on the other hand, your vector is a single number in base 10, with one digit per int (in which case, I'd recommend using char, rather than int), you want something like:

std::ostream&
operator<<( std::ostream& dest, std::vector<int> const& source )
{
    std::vector<int>::const_reverse_iterator current 
        = std::find_if( source.rbegin(), source.rend(),
                        boost::bind( std::not_equal_to<int>(), _1, 0 ) );
    if ( current == source.rend() ) {
        dest << '0';
    } else {
        while ( current != source.rend() ) {
            dest << *current + '0';
            ++ current;
        }
    }
    return dest;
}

(This is for a little endian representation; for bigendian, replace the reverse iterators with normal iterators.)

Again, you'll probably want to handle width() and fill(); handling the base would be significantly more difficult.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • i am just beginner, there's so much new things for me in your code. i have found the simplier solution in first answer. maybe your solution is better and faster, i don't know, but for know i think i am ok with that char c = someInt+'0';. anyway thanks very much, i will take a look on it when i will be experienced enough to understand it :) – user1145902 Jan 31 '12 at 15:40
  • @user1145902 My code uses the `someint + '0'` for the individual ints. What it does in addition is address the issues of formatting; just a sequence of integers isn't (usually) very useful. – James Kanze Jan 31 '12 at 15:47
  • This answer also includes the boost library in a sneaky fashion. *hisses* – Axle Dec 13 '13 at 21:48
0

Let's say arr[] is your int array. Then you can do:

int size = sizeof(arr) / sizeof(arr[0]); // get size of arr[]
char *intstr = new char[size+1]; // preallocate string 
intstr[size] = 0; // terminate string
for(int i = 0; i < size; i++)
{
    intstr[i] = '0' + arr[i];
}

That's all. Only standards used...

Martin Hennings
  • 16,418
  • 9
  • 48
  • 68
  • Why do people insist on using things like `sizeof( arr ) / sizeof( arr[0] )`? If you really need the size, `std::end( arr ) - std::begin( arr )` is preferable; even more idiomatic would be to rewrite the code to use the iterators returned by these functions. The advantage is that they won't compile if `arr` is a pointer; the `sizeof` expression compiles, but gives wrong results. – James Kanze Jan 31 '12 at 15:37
  • @JamesKanze I just wanted to show that this is possible without the use of any std:: stuff. Of course there are more elegant ways to solve this, but they are also harder to "step through" by thought. – Martin Hennings Jan 31 '12 at 15:49