11

How can I set the cursor at the desired location on the console in C or C++?

I remember a function called gotoxy(x,y), but I think its deprecated. Is there any alternative?

Mat
  • 202,337
  • 40
  • 393
  • 406
user1232138
  • 5,451
  • 8
  • 37
  • 64
  • 2
    That is not part of standard C or C++. You'll have to use an API. What kind of cursor are you referring to? Mouse? Keyboard cursor in terminal? – smocking May 01 '12 at 17:39
  • Once you want something more than a linear text output, get away from the console entirely. There are too many idiosyncracies to worry about, on the developer's side and on the user's side. Get a library that supports 2D graphics([SFML](http://www.sfml-dev.org/), [SDL](http://www.libsdl.org/)), and output text using graphical text output functions. – Benjamin Lindley May 01 '12 at 17:47
  • 2
    If you're on Unix, the `curses` or `ncurses` library provides the facilities you're after. – Jonathan Leffler May 01 '12 at 17:47
  • I am on windows and I am writing a console application. I don't know much about the 2D graphics library.. – user1232138 May 01 '12 at 17:54
  • That's why I provided links. And I'm telling you specifically to get away from the console. It's not made for this. It's made for putting out characters, one after another, in a linear fashion. – Benjamin Lindley May 01 '12 at 17:59
  • 1
    Perhaps you could try some of [these suggestions](http://stackoverflow.com/questions/138153/is-ncurses-available-for-windows) – smocking May 01 '12 at 17:59
  • PDCurses: http://en.wikipedia.org/wiki/PDCurses . You could also look at the code for i.e. Midnight Commander (which is Unix/Win). http://en.wikipedia.org/wiki/Midnight_Commander , Also see http://en.wikipedia.org/wiki/Text_user_interface . – Morpfh May 01 '12 at 18:36
  • 1
    @BenjaminLindley: I disagree. The Windows console is perfectly well suited to many simple 2D text tasks, and it's a whole lot simpler than mucking about with a general-purpose multimedia library. – Harry Johnston May 02 '12 at 02:23

8 Answers8

12

Neither C nor C++ have any notion of a screen or console; they only see streams of bytes, which have no inherent display characteristics. There are a number of third-party APIs like ncurses to help you do that.

If you want a quick-n-dirty solution and the terminal you're working with understands ANSI escape sequences, then you can do things like

printf("\033[%d;%dH", row, col);

to move the cursor to a specific row and column (where the top left corner is {1,1}). You'd be better off using ncurses, though (or the equivalent for your platform).

John Bode
  • 119,563
  • 19
  • 122
  • 198
8

Use SetConsoleCursorPosition.

There are a bunch of other functions in the same part of the MSDN library. Some of them may be useful too.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
4

You can use this to set the cursor to specific coordinates on the screen, and then simply use cout<< or printf statement to print anything on the console:

#include <iostream>
#include <windows.h>

using namespace std;

void set_cursor(int,int);

int main()
{
     int x=0 , y=0;
     set_cursor(x,y);
     cout<<"Mohammad Usman Sajid";

     return 0;
}

void set_cursor(int x = 0 , int y = 0)
{
    HANDLE handle;
    COORD coordinates;
    handle = GetStdHandle(STD_OUTPUT_HANDLE);
    coordinates.X = x;
    coordinates.Y = y;
    SetConsoleCursorPosition ( handle , coordinates );
}
3

In case you are talking about ncurses library, the function you are after is move (row, column).

Septagram
  • 9,425
  • 13
  • 50
  • 81
2

I use a really simple method. You don't overly need to know what a HANDLE is unless you're really diving into console applications, a COORD object is in the windows.h standard library and has two member data intergers X and Y. 0,0 is the top left corner and Y increases to go down the screen. You can use this command and just continue to use std::cout<< to print whatever you need.

#include <windows.h>

int main(void){
//initialize objects for cursor manipulation
HANDLE hStdout;
COORD destCoord;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

//position cursor at start of window
destCoord.X = 0;
destCoord.Y = 0;
SetConsoleCursorPosition(hStdout, destCoord);
}
T.Mahon
  • 21
  • 2
1

This was on stackoverflow...

`#include <stdio.h>

// ESC-H, ESC-J (I remember using this sequence on VTs)
#define clear() printf("\033[H\033[J")

//ESC-BRACK-column;row (same here, used on terminals on an early intranet)
#define gotoxy(x,y) printf("\033[%d;%dH", (y), (x))

int main(void)
{
    clear();
    gotoxy(23, 12);
    printf("x");
    gotoxy(1, 24);
    return 0;
}`
808
  • 7
  • 2
1

For Windows: #include<windows.h>

#define cursor(x, y) SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), (COORD){x, y})

For Linux:

#define cursor(x,y) printf("\033[%d;%dH", x, y)

-1

I figured out this to set the cursor.

#include <iostream>

void setPos(std::ostream& _os, const std::streamsize& _x, const std::streamsize& _y)
{
    char tmp = _os.fill();

    if(_y>0) {
            _os.fill('\n');
            _os.width(_y);
            _os << '\n';
    }
    if(_x>0) {
            _os.fill(' ');
            _os.width(_x);
            _os << ' ';
    }
    _os.flush();
    _os.fill(tmp);
}

int main(int argc, char **argv)
{
    setPos(std::cout, 5, 5);
    std::cout << "foo" << std::endl;
    return 0;
}

To do more you'll need assumptions on the resolution or a lib like ncurses.

lupz
  • 3,620
  • 2
  • 27
  • 43
  • Unlike gotoxy, your function can only move the cursor forward. Also, the position is relative to the current cursor-position in your solution - if the cursor is at (x,y), then a call to setPos(a,b) moves to ((y==0?x:0)+a,y+b) - so the new x-coordinate depends on the parameter you pass for y. – Algoman Aug 18 '17 at 08:27
  • Exactly. It is _shifting_ the output by a desired offset. In fact it does this by producing output. If I recall correctly I used something like this for table-like output formatting. – lupz Aug 18 '17 at 09:07
  • If you print `\r` and then move forward, you can advance to an arbitrary column, right? You would only be able to control the Y coordinate if you knew the width of the terminal, since the output would naturally wrap at intervals of that. If it works at all, I would start with a `\r` or `\n` to make sure you're starting at (0,0), and make sure nothing prints at the same time. – John P Sep 28 '17 at 22:41