0

I want to write something using printf while also centering the x coordinate and y=0.

How can I center the x coordinate? For example someone might have their compiler window open in fullscreen and others might not? I want the text in the middle. Right now x is assigned a random value (50)

#include <stdio.h>
#include <conio.h>

int main()
{
    gotoxy(50,0);

    printf("Test");

    return 0;
}
hyde
  • 60,639
  • 21
  • 115
  • 176
alcatraz
  • 41
  • 2
  • 6

1 Answers1

0

I'm just using an online compiler right now. onlinegdb.com Was thinking if there was a way to center the x so that it's the same in every compiler.

What is possible or not isn't determined by the compiler you are using, but by the platform and the ammount of code you are prepared to write.

Standard C has no idea of consoles, windows and other platform dependent stuff. If you want to get to know something about your consoles properties you have to ask the console/operating system. There are also libraries like ncurses for POSIX that allowes different terminals POSIX systems can run on to be treated uniformly.

An implementation of the ncurses-library that is available for DOS, OS/2, Win32, X11 and SDL is PDCurses. It can be used to write platform agnostic code.

But since you mentioned that your platform is windows, here is a solution that uses only the WinAPI:

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

#include <windows.h>

COORD get_console_dimensions(void)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    COORD dimensions = { csbi.srWindow.Right - csbi.srWindow.Left,
                         csbi.srWindow.Bottom - csbi.srWindow.Top };
    return dimensions;
}

COORD get_console_cursor_pos(void)
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    return csbi.dwCursorPosition;
}

void gotoxy(short x, short y)
{
    COORD pos = { x, y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void puts_centered(char const *str)
{
    size_t length = strlen(str);
    short x = (short)(get_console_dimensions().X - length) / 2;
    gotoxy(x, get_console_cursor_pos().Y);
    puts(str);
}

int main(void)
{
    puts_centered("Hello, World!");
}

Using ncurses the same can be achieved (also works with PDCurses, include <curses.h> instead of <ncurses.h>):

#include <string.h>

#include <ncurses.h>

int main(void)
{
    initscr();
    int max_x = getmaxx(stdscr);
    int y, x;
    getyx(stdscr, y, x);
    char const *str = "Hello, World!\n";
    mvaddstr(y, (max_x - strlen(str)) / 2, str);
    refresh();
    // endwin(); // *)
}

Live: https://onlinegdb.com/HkIpXBUim

Please note that OnlineGDBs support for ncurses with its "terminal" is broken. getyx() won't tell the real width of its console.

*) Documentation says you should call endwin() before exiting your program. If you do so with OnlineGDB you won't get any visible output at all from OnlineGDB. Only if you click the "Copy output to clipboard"-button and view the copied text you'll see the ANSI escape sequences produced by ncurses.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • [It doesn't quite work](https://onlinegdb.com/rJibgVIoQ) with OP's current compiler. – n. m. could be an AI Oct 18 '18 at 16:10
  • @n.m. [It doesn't quite work](https://onlinegdb.com/HkIpXBUim) with OP's current compiler despite using ncurses that OnlineGDB claims to support. – Swordfish Oct 18 '18 at 17:39
  • It works quite a lot better than the windows based solution though. It compiles, it runs, and it behaves as if the terminal is 80 characters wide. Which is not exactly unreasonable in a browser based environment. But that's not the point. The point is, OP's original conio.h based program also works there. – n. m. could be an AI Oct 18 '18 at 19:17