【问题标题】:idiomatic way to sanitize a string for printing to a terminal?清理字符串以打印到终端的惯用方法?
【发布时间】:2014-05-03 07:44:26
【问题描述】:

我在内存中有这个字符串,我想将其打印到终端或日志文件 - 不会出现垃圾/不可打印字符,这会限制我的风格。所以,而不是

my_output_stream << my_string;

我想做

my_output_stream << sanitize(my_string);

或许

sanitize_to(my_output_stream, my_string);

是否有一些惯用/标准的工具可以做到这一点?

【问题讨论】:

  • 如何在字符串中获取垃圾值?事先检查那里发生的事情不是更好吗?要进行清理,您可能需要检查可打印的字符,并将它们替换为 s.th。人类可读(如转义字符表示)。
  • @πάνταῥεῖ:由于各种错误,我可以将它们放在我的字符串中:-)
  • 对于记录器类等来说绝对有意义,但正如我在答案中提出的补充内容中提到的那样,您可能会给出可打印的表示,而不是“扔掉”不可打印的字符。

标签: c++ string output sanitization idioms


【解决方案1】:

惯用的方法是过滤不可打印的内容。

我知道没有现成的方法,但写一个很容易:看到它Live On Coliru

#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>

template <typename It>
std::string sanitize(It f, It l) { 
    std::ostringstream oss;
    for (;f!=l;++f)
    {
        if((std::isgraph(*f) || std::isspace(*f)) && *f != '\r' && *f != '\n')
            oss << *f;
        else
            oss << "%" << std::hex << std::setw(2) << std::setfill('0') << 
                static_cast<unsigned>(static_cast<unsigned char>(*f));
    }
    return oss.str();
}

template <typename C>
std::string sanitize(C const& c) { 
    using std::begin;
    using std::end;

    return sanitize(begin(c), end(c));
}

int main()
{
    std::cout << sanitize("Hello\tworld\r\n. §1.3 \b") << "\n";
}

【讨论】:

    【解决方案2】:

    cctype 库有一个 isprint() 函数,如果字符可打印,则返回 true。您可以使用它来检查字符串中的字符是否可打印,并且,如果它是可打印的,则让它打印该字符,如果不是,则不执行任何操作。

    【讨论】:

    • Mark:谢谢,我知道,但我希望不要“自己动手”字符串消毒剂。此外,如果字符不可打印,您应该打印什么内容也不清楚。
    • @einpoklum 确实,如果字符不可打印,您没有明确说明应该打印什么(明白了吗?决定要求)。我的答案 - 随机 - 选择了 'url-encoding' 样式,例如%08\b
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2018-07-21
    • 1970-01-01
    • 2019-11-11
    • 2012-01-09
    • 2015-05-23
    • 2017-01-15
    • 2021-11-08
    相关资源
    最近更新 更多