vddox
vddox

Reputation: 182

Optimize inserting std::uint32_t's into a std::vector<char>

I'm attempting to insert an array of unsigned ints into a std::vector.

Here is my current code:

auto add_chars(std::vector<char> & vec, unsigned val[]){
    std::string tmp;
    tmp.resize(11) // Max chars a uint can be represented by, including the '\n' for sprintf
    for (auto x = 0; x< 10; x++){
        auto char_count = sprintf(tmp.data(),"%u", val[x]);
        vec.insert(vec.begin()+vec.size(),tmp.data(), tmp.data()+char_count);
    }

}

int main(){
    std::vector<char> chars;
    unsigned val[10] {1,200,3,4,5,6000,7,8,9000};
    add_chars(chars,val);
    for (auto & item : chars){
        std::cout << item;
    }
}

This solution works, however I question its efficiency (and elegance).

Two questions:

*edit Fixed a bug in the code made while transferring over to here.

Also, i'm aware that '9000' can't be represented as 1 char, whats why im using the buffer and sprintf to generate multiple chars for the one uint.

Upvotes: 0

Views: 975

Answers (2)

eerorika
eerorika

Reputation: 238411

Is there a more idiomatic way of doing this?

A character stream is idiomatic for this. Unfortunately, the standard only has a stream for building a string; not a vector. You can copy the string into a vector though. This is not most efficient way:

std::ostringstream ss;
unsigned val[10] {1,200,3,4,5,6000,7,8,9000};
for (auto v : val)
    ss << v;
std::string str = ss.str();

// if you need a vector for some reason
std::vector<char> chars(std::begin(str), std::end(str));

Or you could write your own custom vector stream, but that will be a lot of boilerplate.

Upvotes: 4

john
john

Reputation: 87972

I would make a couple of changes (and fix the bug).

Firstly the number of digits in an integer is limited so there's no need to use a dynamic object like std::string, a simple char array will do. Since you are using uint32_t and decimal digits 10 characters are sufficient, 11 if you include a nul terminator.

Secondly sprintf and similar are inefficient because they have to interpret the format string, "%u" in your case. A hand written function to perform the conversion from uint32_t to digits would be more efficient.

Upvotes: 2

Related Questions