Change colour of specific characters in string in C

712 Views Asked by At

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

2

There are 2 best solutions below

0
chqrlie On BEST ANSWER

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;
}
2
Onur Turhan On

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]));
}