c - 为什么 ANSI 在第一次调用函数时打印代码并在第二次调用时打印颜色?

标签 c colors printf

我正在尝试更改 connect 4 游戏中 printf 语句的颜色输出。我做了一个功能来设置打印颜色并重置它。它适用于我的大部分代码,但不适用于第一次调用它时调用的第一个函数,但从那里开始工作。所讨论的函数是主程序中调用的第一个函数。

我尝试了函数的不同定位,将它定位在函数调用位置的任一侧,并将颜色代码直接输入到 printf 函数中,但它总是第一次失败(而且只有第一次)。

#include <stdio.h>
void sprint_green();
void sprint_red();
int main_menu ( void ){
    int a = 0;
    char opt [20];
    sprint_red();
    printf("============================\n");
    printf("    Welcome to Connect4!\n");
    printf("============================\n");
    sprint_reset();
    // Continue asking for an option until a valid option (n/l/q) is entered
    while (a == 0)
    {
        sprint_green();
        printf("(N)ew game\n(L)oad game\n(Q)uit");
        sprint_reset();
        fgets(opt, 20, stdin);
    // if 'n', return 1
        if(opt[0] == 'n' || opt[0] == 'N'){
            a = 1;
        }
    // if 'l', return 2
        else if(opt[0] == 'l' || opt[0] == 'L'){
            a = 2;
        }
    // if 'q', return -1
        else if(opt[0] == 'q' || opt[0] == 'Q'){
            a = -1;
            printf("\nGoodbye!\n");
        }
    // if anything else, give error message and ask again..
        else
        {
            printf("Invalid option\n");
        }
    }
    system("cls");
    return(a);
}

int main (void)
{
    int i;

    for(i = 0; i < 5; i++)
    {
        main_menu();
    }
}

void sprint_green()
{
  printf("\033[1;32m");
}

void sprint_red()
{
  printf("\033[1;31m");
}

void sprint_reset()
{
  printf("\033[0m");
}

前三个 printf 语句预计以红色打印,下一个以绿色打印。然而,它第一次被称为打印 ANSI 颜色代码。

[1;31m============================
    Welcome to Connect4!
============================
[0m[1;32m(N)ew game
(L)oad game
(Q)uit[0m

但是,在运行一次游戏并重新开始(不关闭终端)后,这些功能会按预期工作。

最佳答案

默认情况下,Windows 命令外壳不启动 vt100 仿真。正如@Bodo 在他的回答中指出的那样,这可以通过运行 shell 命令 cls 来触发。但是,从技术上讲,shell 命令不需要是 cls 甚至根本不需要有效的命令。您只需一个空的 system("") 调用即可触发它!这也是可移植的,因为它除了暂时启动一个 shell 实例并终止它之外什么都不做。因此它在 Windows 或 Linux 环境中应该同样可以正常工作。

修复代码:

#include <stdio.h>
#include <stdlib.h> // for system()

void sprint_green();
void sprint_red();
int main_menu ( void ){
    int a = 0;
    char opt [20];
    system(" "); // Trigger ANSI emulation
    sprint_red();
    printf("============================\n");
    printf("    Welcome to Connect4!\n");
    printf("============================\n");
    sprint_reset();
    // Continue asking for an option until a valid option (n/l/q) is entered
    while (a == 0)
    {
        sprint_green();
        printf("(N)ew game\n(L)oad game\n(Q)uit");
        sprint_reset();
        fgets(opt, 20, stdin);
    // if 'n', return 1
        if(opt[0] == 'n' || opt[0] == 'N'){
            a = 1;
        }
    // if 'l', return 2
        else if(opt[0] == 'l' || opt[0] == 'L'){
            a = 2;
        }
    // if 'q', return -1
        else if(opt[0] == 'q' || opt[0] == 'Q'){
            a = -1;
            printf("\nGoodbye!\n");
        }
    // if anything else, give error message and ask again..
        else
        {
            printf("Invalid option\n");
        }
    }
    system("cls");
    return(a);
}

int main (void)
{
    int i;

    for(i = 0; i < 5; i++)
    {
        main_menu();
    }
}

void sprint_green()
{
  printf("\033[1;32m");
}

void sprint_red()
{
  printf("\033[1;31m");
}

void sprint_reset()
{
  printf("\033[0m");
}

关于c - 为什么 ANSI 在第一次调用函数时打印代码并在第二次调用时打印颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58165576/

相关文章:

C:使用查找表评估一组有限的小整数值的函数的最快方法?

c - 如何在 Linux 中将星号作为命令行参数?

java - 根据 HTML 十六进制颜色计算 ARGB 整数

colors - 可以在python中更改默认错误颜色吗?

android - 黑透明和白透明有区别吗?

php - 使用 'printf' 返回字符串,而不是打印它

c - printf 从 char 到 int 的转换太聪明了?

unix - 将命令输出 append 到不带换行符的文件

java - 如何在 Mac OS X 中使用带有 Java 的 Windows DLL?

c - 无效写入大小 : memset