Thread: ANSI Coloring not working

  1. #1
    Registered User
    Join Date
    Nov 2015
    Posts
    72

    ANSI Coloring not working

    I'm trying to generate different colors to enhance the visibility of the output from the programs I'm writing but it's not working no matter what I do.

    I'm on a Windows 7 x64 environment with a UTF-8 encoded command line prompt. I have checked that the terminal is fully capable of generating ANSI colors.

    I think the problem is with the escape character that gets mangled by the printf() command. When using '\0033' or '\x1b' or even the escape character itself, the output becomes 'â†' instead of the true escape character when encoding it in ANSI (i.e. non-unicode).

    Does anyone know what's going on and/or how to get around this? Strangely, I cannot find any solution elsewhere and I'm currently restricted to using C and VisualStudio. I can't see that the lacking ANSI.sys support is the problem here either as it is a character that get's mangled in the conversion to unicode or whatever is taking place.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Why not use proper functions to manipulate terminal colors, instead of ANSI escape sequences, which are hard to read and debug. Try something like SetConsoleTextAttribute. It's part of the Windows API, available on pretty much any modern-ish Windows system.

  3. #3
    Registered User
    Join Date
    Nov 2015
    Posts
    72
    I cannot see how escape sequences would be hard to debug. After all, no matter what method you use to produce color in a terminal, it won't be without producing an escape sequence of some kind.

    Now, I've seen the 'SetConsoleTextAttribute' function, but it seems to be a global attribute it manipulates and I cannot see how you can use that function efficiently to highlight parts of printf() output text with colors.
    Last edited by bot; 11-10-2015 at 07:08 AM.

  4. #4
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    What is your printf() statement?

    Edit: Also, how are you making sure your console supports ANSI escape sequences? I don't think Window 7 console does... (lacking ANSI.sys is the problem)
    Last edited by Hodor; 11-10-2015 at 07:35 AM.

  5. #5
    Registered User
    Join Date
    Nov 2015
    Posts
    72
    Quote Originally Posted by Hodor View Post
    What is your printf() statement?

    Edit: Also, how are you making sure your console supports ANSI escape sequences? I don't think Window 7 console does... (lacking ANSI.sys is the problem)
    A lot of commands/programs that I use outputs in color, 'vim' (yes, there is a Windows version of vim too!) is one such program. If I have a text file with escape color codes written in by hand by a text editor, a command such as 'type <ANSI text file>' will output colors. Even when copying and pasting text with color escape codes into the terminal, the pasted content is immediately shown in color. So yeah, the console/terminal is fully capable of producing color out of ANSI escape codes.

    I have tried various printf() statements, how about these:

    printf("\033[1;32mArrays don't match!\033[0m\n";
    printf("\x1b[1;32mArrays don't match!\x1b[0m\n";
    printf("ESC[1;32mArrays don't match!ESC[0m\n";

    where ESC is the true escape character. All of these yield the same output as in the first post above, i.e. the escape character turns into ''â†'...
    Last edited by bot; 11-10-2015 at 08:01 AM.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Debugging invisible code is the hardest.

  7. #7
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    How do you know that "type" and paste do not pre-convert the escape sequences into calls to SetConsoleTextAttribute() as they are inserting stuff into the console output? If I use printf() to output ANSI escape sequences to a "console" that I am sure supports ANSI escape sequences it works perfectly (e.g. Konsole)

    Edit: Also, I don't know what vim has to do with anything. AFAIK, vim uses ncurses so what it actually sends to the console is... well, whatever it sends. I doubt it sends ANSI escape sequences.
    Last edited by Hodor; 11-10-2015 at 08:05 AM.

  8. #8
    Registered User
    Join Date
    Nov 2015
    Posts
    72
    I can't see how escape sequences are "invisible". Ok, I managed to launch a hex editor to further analyze the difference between the real escape character and the garbage that the printf() command produces:

    Real escape character: 0x1B (0001 1011)
    Printf escape garbage: 0xE28690 (0000 0000 1110 0010 1000 0110 1001 0000)

    If it doesn't "pre-convert", then why does the output character have an ANSI/UNICODE value that is different from what I commanded the printf() to output in first place? If ANSI is disabled, I should either get a non-character or a character with the same character code as inputted. Something is broken here.

    vim is most likely using ANSI escape code based colors for syntax highlighting etc. This is confirmed by the fact that the same colors are present when using Windows vim over an ssh terminal with command.com or other dos-shell (such as 4NT) as a login shell for the windows based ssh-server.
    Last edited by bot; 11-10-2015 at 08:49 AM.

  9. #9
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by bot View Post
    I can't see how escape sequences are "invisible". Ok, I managed to launch a hex editor to further analyze the difference between the real escape character and the garbage that the printf() command produces:

    Real escape character: 0x1B (0001 1011)
    Printf escape garbage: 0xE28690 (0000 0000 1110 0010 1000 0110 1001 0000)
    We don't know what your printf() command actually is (therefore it's invisible).

    Edit: I see you edited your post.
    Last edited by Hodor; 11-10-2015 at 08:41 AM.

  10. #10
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        char test[100];
        size_t i;
        
        sprintf(test, "\x1b[1;32mArrays don't match!\x1b[0m\n"); 
        
        for (i = 0; i < strlen(test); i++) {
            printf("%02x ", test[i]);
        }
        
        printf("\n");
            
        return 0;
    }
    I see no problem with the crap printf() is outputting

  11. #11
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(void)
    {
        FILE *fp;
        
        if ((fp = fopen("ansi.txt", "w")) == NULL) {
            perror("Error:");
            exit(1);
        }
        
        fprintf(fp, "\x1b[1;32mArrays don't match!\x1b[0m\n"); 
        
        fclose(fp);
        
        return 0;
    }
    ANSI Coloring not working-ansi_txt-jpg

    And, again, I see no problem in the hex editor.

  12. #12
    Registered User
    Join Date
    Nov 2015
    Posts
    72
    ... but adding the line

    Code:
    printf(test);
    will yield the same issues I mentioned in the first post. I discovered now that 'ansiOutputExecutable.exe > tstfile.txt' yields proper escape characters in the file but not when outputting directly to the console/terminal.

    So I have a workaround albeit a bit clunky:

    Code:
    DOS-Shell > ansiOutputExecutable.exe | type
    does output ANSI colored text, at least in 4NT shell or the 'Take Command'/TCC Prompt. Too bad I have to use the windows command prompt to get the visual studio paths set up to the linker/compilers ...
    Last edited by bot; 11-10-2015 at 09:12 AM.

  13. #13
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    And what does my second example do? (if you "type ansi.txt")?

  14. #14
    Registered User
    Join Date
    Nov 2015
    Posts
    72
    It outputs color in the TCC shell and the same broken character in the windows shell. But vim is in color in both shells. Too bad ncurses isn't available for visual studio which is needed for the nvcc compiler I'm working with. It doesn't get neat when working with the SetConsoleTextAttribute() as that command seems to set the attribute on the entire text and not parts of it. It seems that the command.com de

  15. #15
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    That your pipe command does what you expect (and using type to output ansi.txt) suggests to me that it is "type" that is parsing the escape sequences and not the shell itself.

    Edit: The default Windows shell does not support ANSI escape sequences.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pre-ANSI to ANSI - Unix to Linux
    By petterk in forum C Programming
    Replies: 12
    Last Post: 04-20-2015, 07:56 AM
  2. Coloring My Text
    By bjl in forum C++ Programming
    Replies: 10
    Last Post: 02-05-2008, 07:37 PM
  3. ANSI - working with directories
    By sean345 in forum C Programming
    Replies: 1
    Last Post: 06-01-2002, 04:43 PM
  4. Coloring Buttons
    By Okiesmokie in forum Windows Programming
    Replies: 5
    Last Post: 03-17-2002, 07:00 AM
  5. What is the Difference between ANSI C and non-ANSI C ?
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 11-24-2001, 06:55 AM