使用C更改文字颜色
我一直在阅读一些有关使用C更改文本颜色的文章,但问题在于它们都倾向于与Turbo 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
textcolor(RED);
而且我需要更改 variable:value(用户输入)输出的颜色,类似于在终端程序上执行"inxi -S"时得到的颜色.如何更改控制台程序的颜色?
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. How do I change the color of my console program?
只能部分回答该问题,因为不指定彩色输出,它只知道文本.因此,解决方案取决于目标平台,从注释中可以明显看出,OP对多个平台都感兴趣.
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.
我做了一段时间自己的实现,可以在支持ANSI颜色的* nix终端和win32
控制台中使用,我已经在注释中提到过,但是要得到答案,应将其简化为最低限度,所以这是一个例子:
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:
#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 apppropriate sequence:
fputs(ansiColorSequences[color], stream);
}
}
#endif
注释1 :我的原始代码还有其他功能,包括通过管道发送ansi颜色代码,可能不是您想要的,具体取决于您的位置预期输出将通过管道传递到.它还具有类似于printf()
的支持颜色的界面.您可以在此处在核心"库中找到它.
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. It also has a printf()
like interface supporting colors. You can find it here, in the "core" library.
注释2 :如果您最终想用自己的终端做更多的事情,而不仅仅是颜色,例如控制光标,输出到固定位置等,建议您使用诅咒反而. Linux系统上的默认实现是 ncurses ,对于Windows,您可以使用
Note 2: If you ultimately want to do more with your terminal than just colors, like e.g. controlling the cursor, outputting to a fixed position, etc, I suggest you use curses instead. 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.