简体   繁体   English

使用 C 更改文本颜色

[英]Change text color using C

I've been reading some few articles about changing text color using C, but the problem is they all tend to be related to Turbo C我一直在阅读一些关于使用 C 更改文本颜色的文章,但问题是它们都与 Turbo C 有关

textcolor(RED);

And I have a need to change the color of variable: value (user input) output similar to what we get when we execute "inxi -S" on terminal program.而且我需要更改变量的颜色:值(用户输入)输出类似于我们在终端程序上执行“inxi -S”时得到的输出。 How do I change the color of my console program?如何更改控制台程序的颜色?

This question can only be partially answered because doesn't specify colored output, it only knows about text.这个问题只能部分回答,因为没有指定彩色输出,它只知道文本。 So solutions are dependent on the target platform and from the comments, it's clear the OP is interested in more than one platform.所以解决方案取决于目标平台,从评论中可以看出,OP 对不止一个平台感兴趣。

I did my own implementation a while back that works in *nix terminals supporting ANSI colors and in a win32 console, which I already referred to in comments, but for an answer, this should be simplified to the bare minimum, so here comes an example:不久前我做了我自己的实现,它在支持 ANSI 颜色的 *nix 终端和win32控制台中工作,我已经在评论中提到过,但是对于答案,这应该被简化到最低限度,所以这里有一个例子:

#ifdef _WIN32
#include <windows.h>    // for win32 API functions
#include <io.h>         // for _get_osfhandle()
#else
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE   // enable POSIX extensions in standard library headers
#endif
#include <unistd.h>     // for isatty()
#endif

#include <stdlib.h>
#include <stdio.h>

// use an enum for platform-independent interface:
typedef enum TextColor
{
    TC_BLACK = 0,
    TC_BLUE = 1,
    TC_GREEN = 2,
    TC_CYAN = 3,
    TC_RED = 4,
    TC_MAGENTA = 5,
    TC_BROWN = 6,
    TC_LIGHTGRAY = 7,
    TC_DARKGRAY = 8,
    TC_LIGHTBLUE = 9,
    TC_LIGHTGREEN = 10,
    TC_LIGHTCYAN = 11,
    TC_LIGHTRED = 12,
    TC_LIGHTMAGENTA = 13,
    TC_YELLOW = 14,
    TC_WHITE = 15
} TextColor;

// set output color on the given stream:
void setTextColor(FILE *stream, TextColor color);

int main(void)
{
    puts("Color test.");
    setTextColor(stdout, TC_GREEN);
    puts("This is green!");
    setTextColor(stdout, TC_LIGHTGRAY);
    puts("back to normal.");
    return EXIT_SUCCESS;
}

#ifdef _WIN32

void setTextColor(FILE *stream, TextColor color)
{
    int outfd = fileno(stream);
    HANDLE out = (HANDLE)_get_osfhandle(outfd);
    DWORD outType = GetFileType(out);
    DWORD mode;
    if (outType == FILE_TYPE_CHAR && GetConsoleMode(out, &mode))
    {
        // we're directly outputting to a win32 console if the file type
        // is FILE_TYPE_CHAR and GetConsoleMode() returns success

        SetConsoleTextAttribute(out, color);
        // the enum constants are defined to the same values
        // SetConsoleTextAttribute() uses, so just pass on.
    }
}

#else

static const char *ansiColorSequences[] =
{
    "\x1B[0;30m",
    "\x1B[0;34m",
    "\x1B[0;32m",
    "\x1B[0;36m",
    "\x1B[0;31m",
    "\x1B[0;35m",
    "\x1B[0;33m",
    "\x1B[0;37m",
    "\x1B[1;30m",
    "\x1B[1;34m",
    "\x1B[1;32m",
    "\x1B[1;36m",
    "\x1B[1;31m",
    "\x1B[1;35m",
    "\x1B[1;33m",
    "\x1B[1;37m"
};

static const char *ansiColorTerms[] =
{
    "xterm",
    "rxvt",
    "vt100",
    "linux",
    "screen",
    0
    // there are probably missing a few others
};

// get current terminal and check whether it's in our list of terminals
// supporting ANSI colors:
static int isAnsiColorTerm(void)
{
    char *term = getenv("TERM");
    for (const char **ansiTerm = &ansiColorTerms[0]; *ansiTerm; ++ansiTerm)
    {
        int match = 1;
        const char *t = term;
        const char *a = *ansiTerm;
        while (*a && *t)
        {
            if (*a++ != *t++)
            {
                match = 0;
                break;
            }
        }
        if (match) return 1;
    }
    return 0;
}

void setTextColor(FILE *stream, TextColor color)
{
    int outfd = fileno(stream);
    if (isatty(outfd) && isAnsiColorTerm())
    {
        // we're directly outputting to a terminal supporting ANSI colors,
        // so send the appropriate sequence:
        fputs(ansiColorSequences[color], stream);
    }
}

#endif

Note 1 : My original code does a little more, including sending ansi color codes through pipes as well, this might not be what you want, depending on where you expect output to be piped to.注 1 :我的原始代码做了更多的工作,包括通过管道发送 ansi 颜色代码,这可能不是您想要的,具体取决于您希望将输出通过管道传输到何处。 It also has a printf() like interface supporting colors.它还有一个类似printf()界面支持颜色。 You can find it here, in the "core" library .您可以在此处的“核心”库中找到它。

Note 2 : If you ultimately want to do more with your terminal than just colors, like eg controlling the cursor, outputting to a fixed position, etc, I suggest you use curses instead.注意 2 :如果您最终想对终端做更多的事情而不仅仅是颜色,例如控制光标,输出到固定位置等,我建议您改用curses The default implementation on Linux systems is ncurses , for windows you can use pdcurses -- the same code can be built/linked against ncurses or pdcurses, depending on your target platform. Linux 系统上的默认实现是ncurses ,对于 Windows,您可以使用pdcurses —— 可以针对 ncurses 或 pdcurses 构建/链接相同的代码,具体取决于您的目标平台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM