如何在 C++ 中打印彩色文本,同时在没有控制字符的情况下重定向它们(来自源头,而不是后处理)?

发布于 2025-01-14 23:43:53 字数 1817 浏览 4 评论 0原文

我正在尝试进行一些类似 grep 的打印,请参见下文。

#define RED    "\033[0;31m"
#define GREEN  "\033[0;32m"
#define BLUE   "\033[0;34m"
#define END    "\033[0m"

void print_matches(const string& text, const string& pattern,
                   const vector<int>& occurrences)
{
    const int M = occurrences.size();
    const int T = text.size();
    const int P = pattern.size();
    int i = 0, k = 0, line = 1;
    int start_of_line = 0;
    while (k < M && i < T) {
        if (i == occurrences[k]) { // print the whole line
            // follow color scheme of grep
            cout << GREEN << line << END << BLUE << ':' << END;
            for (int j = start_of_line; j != i; ++j)
                cout << text[j];
            // add i < T in case of noeol
            while (i < T && text[i] != '\n') {
                if (i == occurrences[k]) {
                    cout << RED; // highlight matches
                    for (int t = 0; t < P; ++t)
                        cout << text[i++];
                    cout << END;
                    ++k;
                }
                else {
                    cout << text[i++];
                }
            }
            cout << '\n';
        }

        if (text[i] == '\n') {
            ++line;
            start_of_line = i + 1;
        }

        ++i;
    }
}

但我在将结果重定向到输出文件时发现了一个问题。它还保留了 控制字符。

$ printf "\033[0;31mhowdy\n" > tmp  # so does this

例如,有后处理解决方案,请参阅

PS:我阅读了grep的手册页,发现一个环境变量GREP_COLORS可以改变终端上匹配字符串的颜色。我应该使用一些环境吗 变量又如何? (我是UNIX/Linux环境编程的新手,所以如果有什么地方没有说清楚,请指出;或者帮助我编辑,我将不胜感激:)

I am trying to do some grep-like printing, see below.

#define RED    "\033[0;31m"
#define GREEN  "\033[0;32m"
#define BLUE   "\033[0;34m"
#define END    "\033[0m"

void print_matches(const string& text, const string& pattern,
                   const vector<int>& occurrences)
{
    const int M = occurrences.size();
    const int T = text.size();
    const int P = pattern.size();
    int i = 0, k = 0, line = 1;
    int start_of_line = 0;
    while (k < M && i < T) {
        if (i == occurrences[k]) { // print the whole line
            // follow color scheme of grep
            cout << GREEN << line << END << BLUE << ':' << END;
            for (int j = start_of_line; j != i; ++j)
                cout << text[j];
            // add i < T in case of noeol
            while (i < T && text[i] != '\n') {
                if (i == occurrences[k]) {
                    cout << RED; // highlight matches
                    for (int t = 0; t < P; ++t)
                        cout << text[i++];
                    cout << END;
                    ++k;
                }
                else {
                    cout << text[i++];
                }
            }
            cout << '\n';
        }

        if (text[i] == '\n') {
            ++line;
            start_of_line = i + 1;
        }

        ++i;
    }
}

But I found a problem when redirecting the results to a output file. It also preserves the
control chars.

$ printf "\033[0;31mhowdy\n" > tmp  # so does this

There're post-processing solutions, for example, see here. But I don't want to write a script to do that. I want it to work the way grep is (redirecting colored output text without control chars). How can I modify the code to make it behave like grep?

PS: I read the manual page of grep and I found an environment variable GREP_COLORS that can change the color of the matched strings on the terminal. Should I use some environment
variables and how? (I am a newbie to the UNIX/Linux environment programming, so if there're anything I didn't make clear, please point out; or help me edit, which would be truly appreciated :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文