C ++ Sanitize字符串函数

时间:2015-12-11 10:20:55

标签: c++ string

我需要为以下字符构建自己的清理函数:

', ", \, \n, \r, \0 and CTRL-Z

我想确保以下代码可以完成没有副作用的技巧:

#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include <iomanip>
#include <algorithm>    

void sanitize (std::string &stringValue)
{
    stringValue.replace(stringValue.begin(), stringValue.end(), "\\", "\\\\");
    stringValue.replace(stringValue.begin(), stringValue.end(), "'", "\\'");
    stringValue.replace(stringValue.begin(), stringValue.end(), "\"", "\\\"");
    stringValue.replace(stringValue.begin(), stringValue.end(), "\n", "");
    stringValue.replace(stringValue.begin(), stringValue.end(), "\r", "");
    stringValue.replace(stringValue.begin(), stringValue.end(), "\0", "");
    stringValue.replace(stringValue.begin(), stringValue.end(), "\x1A", "");
}

int main()
{
    std::string stringValue = "This is a test string with 'special //characters\n";

    std::cout << stringValue << std::endl;

    sanitize(stringValue);

    std::cout << stringValue << std::endl;
}

此代码无效。错误:

    terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_M_replace
      1 
      1 This is a test string with 'special //characters

原始代码here

1 个答案:

答案 0 :(得分:1)

请参阅我的帖子评论您的replace来电不正确的原因。 "\0"还有另一个问题:

stringValue.replace(stringValue.begin(), stringValue.end(), "\0", "");

\0标记C字符串的结尾,因此它将尝试用空字符串替换空字符串。您似乎要删除\n, \r, \0 and CTRL-Z,在这种情况下,您可以使用erase-remove idiom代替这些:

void sanitize(std::string &stringValue)
{
    // Add backslashes.
    for (auto i = stringValue.begin();;) {
        auto const pos = std::find_if(
            i, stringValue.end(),
            [](char const c) { return '\\' == c || '\'' == c || '"' == c; }
        );
        if (pos == stringValue.end()) {
            break;
        }
        i = std::next(stringValue.insert(pos, '\\'), 2);
    }

    // Removes others.
    stringValue.erase(
        std::remove_if(
            stringValue.begin(), stringValue.end(), [](char const c) {
                return '\n' == c || '\r' == c || '\0' == c || '\x1A' == c;
            }
        ),
        stringValue.end()
    );
}

See it working here