我一直在阅读一些关于使用C更改文本颜色的文章,但问题是它们都与Turbo C有关
textcolor(RED);
我需要更改变量:值(用户输入)输出的颜色,类似于我们在终端程序上执行“inxi -S”时得到的颜色。如何更改控制台程序的颜色?
答案 0 :(得分:4)
这个问题只能部分回答,因为c没有指定彩色输出,它只知道文本。所以解决方案依赖于目标平台,从评论中可以看出,OP对多个平台感兴趣。
我做了我自己的实现,一段时间后工作在* nix终端支持ANSI颜色和win32
控制台,我在评论中已经提到过,但是为了答案,这应该简化为裸最小,所以这里有一个例子:
#ifdef _WIN32
#include <windows.h> // for win32 API functions
#include <io.h> // for _get_osfhandle()
#else
#define _POSIX_SOURCE // enable POSIX extensions in standard library headers
#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()
类似的界面支持颜色。你可以找到它here, in the "core" library。
注2 :如果您最终想要使用终端而不仅仅是颜色,例如控制光标,输出到固定位置等,我建议您改用curses。 Linux系统上的默认实现是ncurses,对于可以使用pdcurses的窗口 - 可以针对ncurses或pdcurses构建/链接相同的代码,具体取决于您的目标平台。