C - program stops when printf('\033c') used

1

My code:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define world_x_size 53
#define world_y_size 50

struct Pixel
{
    char what_here;
};

typedef struct Pixel pixelsArr[world_x_size];

void create_world(pixelsArr *pixels)
{
    int x = 0;
    int y = 0;
    while (y < world_y_size)
    {
        x = 0;
        while (x < world_x_size)
        {
            pixels[x][y].what_here = 'O';

            x++;
        }

        y++;
    }
}

void update_thread(pixelsArr *pixels)
{
    while(1)
    {
        int x = 0;
        int y = 0;
        while (y < world_y_size)
        {
            char output[world_x_size + 1];
            x = 0;
            while (x < world_x_size)
            {
                output[x] = pixels[x][y].what_here;

                x++;
            }

            y++;
            printf(output);
            printf("\n");
        }
        printf('\033c');
    }

    return NULL;
}
int main()
{
    pixelsArr pixels[world_y_size];

    create_world(pixels);

    pthread_t thread;
    pthread_create(&thread, NULL, update_thread, pixels);
    pthread_join(thread, NULL);

    return 0;
}

Before I was using system("cls") to clear the screen, but I've read that printf('\033c') is faster. Unfortunately my program returns -1073741819 (0xC0000005) after this change. I'm using GNU GCC Compiler.

Basically what I'm trying to do is clearing the screen as fast as possible, but system("cls") isn't fast enough. Maybe you got any other idea besides the printf('\033c').

Any thoughts?

c
asked on Stack Overflow Sep 25, 2018 by peon125

4 Answers

4
printf('\033c');

'\033c' is a character constant, not a string. Your compiler should be throwing a warning over this.

Additionally, this escape sequence forces a full reset of the terminal. (Specifically, it's the VT100 RIS sequence.) This is an odd way to try to clear the screen, and may have some effects you don't want, like resetting terminal options or resizing the terminal. Instead, use:

printf("\033[H\033[2J");

which moves the cursor to the home position, then clears the screen, leaving everything else alone.

answered on Stack Overflow Sep 25, 2018 by duskwuff -inactive- • edited Sep 25, 2018 by duskwuff -inactive-
3
printf('\033c');

printf() expects a char const * as its first parameter, not a character constant.

Try

printf("\033c");

instead.

On Windows use SetConsoleMode() to enable virtual terminal sequences:

#include <windows.h>
#include <stdio.h>

int main() {

    HANDLE con_out = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD mode;
    GetConsoleMode(con_out, &mode);
    SetConsoleMode(con_out, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

    printf("Hello!\n");
    getchar();
    printf("\033[H\033[2J");
    getchar();
}
answered on Stack Overflow Sep 25, 2018 by Swordfish • edited Sep 25, 2018 by Swordfish
2

There are multiple problems in your code:

  • The array pixelsArr pixels[world_y_size] is not dereferenced incorrectly in create_world and update_thread, you should index first by y, then by x.

  • '\033c' is a character constant, you should pass a string to printf:

    printf("\033c");
    

    Note however that this escape sequence might not have the desired effect on your system.

  • the array output is not null terminated: passing it to printf has undefined behavior. It is defined with the correct size, but local objects with automatic storage are uninitialized, so the last element in the array is uninitialized. You should set it to '\0' before printing the string.

  • you should not pass a computed string directly to printf as printf(output);. This has undefined behavior if the string contains one or more % characters, which could happen depending on how you update the pixels. Use printf("%s", output); or fputs(output, stdout);.

Here is an improved version:

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

#define world_x_size 53
#define world_y_size 50

struct Pixel {
    char what_here;
};

typedef struct Pixel pixelsArr[world_x_size];

void create_world(pixelsArr *pixels) {
    int x = 0;
    int y = 0;
    while (y < world_y_size) {
        x = 0;
        while (x < world_x_size) {
            pixels[y][x].what_here = 'O';
            x++;
        }
        y++;
    }
}

void update_thread(pixelsArr *pixels) {
    while (1) {
        int x = 0;
        int y = 0;
        while (y < world_y_size) {
            char output[world_x_size + 1];
            x = 0;
            while (x < world_x_size) {
                output[x] = pixels[y][x].what_here;
                x++;
            }
            output[x] = '\0';
            printf("%s\n", output);
            y++;
        }
        printf("\033c");
    }
    return NULL;
}

int main() {
    pixelsArr pixels[world_y_size];

    create_world(pixels);

    pthread_t thread;
    pthread_create(&thread, NULL, update_thread, pixels);
    pthread_join(thread, NULL);

    return 0;
}
answered on Stack Overflow Sep 25, 2018 by chqrlie • edited Sep 25, 2018 by chqrlie
1

You are accessing pixels items incorrectly: Change it

            output[x] = pixels[x][y].what_here;

to

            output[x] = pixels[y][x].what_here;

look at this definition:

pixelsArr pixels[world_y_size];

pixels can be treated as Pixel [world_y_size][world_x_size].

And pixels[x][y].what_here = 'O'; to pixels[y][x].what_here = 'O';.

answered on Stack Overflow Sep 25, 2018 by rafix07 • edited Sep 25, 2018 by rafix07

User contributions licensed under CC BY-SA 3.0