Search code examples
ccolorsparameter-passingcommand-line-argumentsargv

Colortext program doesn't color properly


I'm trying to make a simple "color text" program in C that uses windows.h to change the terminal color (command-line program) and compiling using tcc. However, instead of working like it should, it picks a random color depending on the text given (Even control characters!), instead of actually just normally passing the number. How would i fix that?

#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[]) {
    if (argc >= 3) {
        printf("Too many arguments specified.");
        return 1;
    }
    if (argc == 1) {
        printf("No arguments specified. Please specify one.");
        return 1;
    }
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), *argv[1]);
    return 0;
}

So, if i for example type 0 (which should bring me to all black text), i instead get this:

not expected, should just make it black

EDIT: Looks like changing *argv[1] to strlen(argv[1]); worked. However, now it depends on the length of the input specified, rather than the number given. It atleast sets the background and foreground correctly (a length of 0 gives an error, a length of 1 changes it to 1, a length of whatever sets it to whatever, etc.), and using a "anti strlen" (takes a number, and makes a string with the number many letters, and returns it) doesn't work.

EDIT: Using atoi(); fixed my problem:

#include <windows.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), atoi(argv[1]));
    return 0;
};

enter image description here


Solution

  • You are getting the color you specified.

    Here is why: ".. instead of actually just normally passing the number ..." but argv[1] does not "pass a number"! Program arguments are always passed as strings.

    SetConsoleTextAttribute sets the console character color to the value provided. The character attributes are defined by bits, but that MSDN page only lists their symbolic names. Looking in wincon.h shows their actual assignments:

    #define FOREGROUND_BLUE 1
    #define FOREGROUND_GREEN    2
    #define FOREGROUND_RED  4
    #define FOREGROUND_INTENSITY    8
    #define BACKGROUND_BLUE 16
    #define BACKGROUND_GREEN    32
    #define BACKGROUND_RED  64
    #define BACKGROUND_INTENSITY    128
    

    What value do you sent, then? The first character of the string "0" – that is, a decimal code of 48, or in hex 0x30. This – look at the defines – comes down to BACKGROUND_BLUE + BACKGROUND_GREEN = cyan.

    The funny thing is, since you want black-on-black, there is no obvious way to enter a binary 0 as a command argument. I suggest you enter the required color code in decimal or hex notation, rather than as a "raw" value, and use strtol or a similar function to convert it to a binary value.