Home > Blockchain >  Change colour of specific characters in string in C
Change colour of specific characters in string in C

Time:06-11

Say I have some ASCII art in string presented as a variable as follows:

    char LOGO[3][40] = {
    "   /$$    /$$                       ",
    "  | $$   |__/                       ",
    " /$$$$$$  /$$/$$$$$$$ /$$   /$$     ",

I want to specifically show the $ with a green colour within the terminal. The classic way of doing so is using ANSI escape codes between an instance/s of $. Unfortunately, this is not viable since I have much more than three lines of this string, and it would be exhausting to do so manually.

Is there a much more viable way of changing the colour of specific characters within a string?

TIA

CodePudding user response:

Not sure that solution with macros available, but an unefficient solution with an extra function is below:

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

#define ORIG_CHAR   "$"    
#define GREEN_CHAR   "\033[32m$\033[0m"     

#define NEW_STRING(n) str_replace( n, ORIG_CHAR, GREEN_CHAR)
      
char LOGO[3][40] = {
"   /$$    /$$                       ",
"  | $$   |__/                       ",
" /$$$$$$  /$$/$$$$$$$ /$$   /$$     ",
};  

  // You must free the result if result is non-NULL.
char *str_replace(char *orig, char *rep, char *with) {
    char *result; // the return string
    char *ins;    // the next insert point
    char *tmp;    // varies
    int len_rep;  // length of rep (the string to remove)
    int len_with; // length of with (the string to replace rep with)
    int len_front; // distance between rep and end of last rep
    int count;    // number of replacements

    if (!orig || !rep)
        return NULL;
    len_rep = strlen(rep);
    if (len_rep == 0)
        return NULL; 
    if (!with)
        with = "";
    len_with = strlen(with);

    ins = orig;
    for (count = 0; tmp = strstr(ins, rep);   count) {
        ins = tmp   len_rep;
    }

    tmp = result = malloc(strlen(orig)   (len_with - len_rep) * count   1);

    if (!result)
        return NULL;

    while (count--) {
        ins = strstr(orig, rep);
        len_front = ins - orig;
        tmp = strncpy(tmp, orig, len_front)   len_front;
        tmp = strcpy(tmp, with)   len_with;
        orig  = len_front   len_rep; // move to next "end of rep"
    }
    strcpy(tmp, orig);
    return result;
}
  
void main(){
    for(int ii=0; ii < sizeof(LOGO)/40; ii  )
        printf("%s\n", NEW_STRING(LOGO[ii]));
}

CodePudding user response:

If your goal is to produce green characters on the terminal, you do not need to change the definition of the logo, just test the characters and output the escape sequences as required:

#include <stdio.h>

char const LOGO[3][40] = {
    "   /$$    /$$                       ",
    "  | $$   |__/                       ",
    " /$$$$$$  /$$/$$$$$$$ /$$   /$$     ",
};

int main() {
    int green = 0;
    for (size_t row = 0; row < sizeof(LOGO) / sizeof(LOGO[0]); row  ) {
        for (size_t col = 0; col < sizeof(LOGO[0]) / sizeof(LOGO[0][0]); col  ) {
            char c = LOGO[row][col];
            if (c == '$') {
                if (!green) {
                    green = 1;
                    printf("\033[32m");
                }
            } else {
                if (green) {
                    green = 0;
                    printf("\033[0m");
                }
            }
            putchar(c);
        }
        if (green) {
            green = 0;
            printf("\033[0m");
        }
        putchar('\n');
    }
    return 0;
}
  • Related