Escaping a C++ string

31,131

Solution 1

Take a look at the Boost's String Algorithm Library. You can use its is_print classifier (together with its operator! overload) to pick out nonprintable characters, and its find_format() functions can replace those with whatever formatting you wish.

#include <iostream>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>

struct character_escaper
{
    template<typename FindResultT>
    std::string operator()(const FindResultT& Match) const
    {
        std::string s;
        for (typename FindResultT::const_iterator i = Match.begin();
             i != Match.end();
             i++) {
            s += str(boost::format("\\x%02x") % static_cast<int>(*i));
        }
        return s;
    }
};

int main (int argc, char **argv)
{
    std::string s("a\x01");
    boost::find_format_all(s, boost::token_finder(!boost::is_print()), character_escaper());
    std::cout << s << std::endl;
    return 0;
}

Solution 2

Assuming that "easiest way" means short and yet easily understandable while not depending on any other resources (like libs) I would go this way:

#include <cctype>
#include <sstream>

// s is our escaped output string
std::string s = "";
// loop through all characters
for(char c : your_string)
{
    // check if a given character is printable
    // the cast is necessary to avoid undefined behaviour
    if(isprint((unsigned char)c))
        s += c;
    else
    {
        std::stringstream stream;
        // if the character is not printable
        // we'll convert it to a hex string using a stringstream
        // note that since char is signed we have to cast it to unsigned first
        stream << std::hex << (unsigned int)(unsigned char)(c);
        std::string code = stream.str();
        s += std::string("\\x")+(code.size()<2?"0":"")+code;
        // alternatively for URL encodings:
        //s += std::string("%")+(code.size()<2?"0":"")+code;
    }
}

Solution 3

One person's unprintable character is another's multi-byte character. So you'll have to define the encoding before you can work out what bytes map to what characters, and which of those is unprintable.

Solution 4

Have you seen the article about how to Generate Escaped String Output Using Spirit.Karma?

Share:
31,131
Danra
Author by

Danra

I love software R&amp;D, especially software internals. I like researching deep bugs, as well as designing new solutions which require manipulating OS or 3rd party internals. I also enjoy designing and implementing complete projects, combining code and decision making to give the best product for a set of business requirements and constraints. Music and music theory are my passion, so I co-founded Sound Radix to create innovative tools for the music industry.

Updated on July 19, 2022

Comments

  • Danra
    Danra almost 2 years

    What's the easiest way to convert a C++ std::string to another std::string, which has all the unprintable characters escaped?

    For example, for the string of two characters [0x61,0x01], the result string might be "a\x01" or "a%01".