SamTebbs33
SamTebbs33

Reputation: 5647

In C/C++, how do you edit a certain 'coordinate' in stdout?

I've been using Vim a lot lately, and I was wondering how the program manages to change the characters at certain positions in the terminal. For example, when using :rc, it replaces the character under the cursor with c.

I have also seen similar things done with Homebrew, which prints a progress bar to the screen and updates it when necessary.

How is this done in C/C++?

Upvotes: 2

Views: 403

Answers (4)

Edward
Edward

Reputation: 7100

Certainly, using ncurses or similar library is a good answer. An alternative may be to use ANSI Escape Codes to control the cursor in some terminal emulators (but not Windows command shell). For example, this code prints a line in multiple colors and then moves the cursor to 2,2 (coordinates are 1-based with 1,1 being the upper left corner) and prints the word "red" in the color red.

#include <iostream>
#include <string>

const std::string CSI{"\x1b["};
const std::string BLUE{CSI + "34m"};
const std::string RED{CSI + "31m"};
const std::string RESET{CSI + "0m"};

std::ostream &curpos(int row, int col)
{
    return std::cout << CSI << row << ';' << col << 'H';
}

int main() 
{
    std::cout << "This is " << BLUE << "blue" << RESET << " and white.\n";
    curpos(2,2);
    std::cout << RED << "red" << RESET << '\n';
}

Upvotes: 1

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

As mentioned that's not a matter of any C/C++ standard operations provided with stdout or cout (besides writing the necessary control characters to the screen).

Controlling the screen cursor of an ASCII terminal totally depends on implementation of the particular terminal program used, and besides a very narrow set of control characters, there's no standard established.

There are libraries like ncurses for a broader variety of linux terminal implementations, or PDcurses for a windows CMD shell.

Upvotes: 0

Christophe
Christophe

Reputation: 73490

There is no standard way of doing this in C++.

It is done with OS dependent lbiraries, such as curses and similar libraries (ncurses) in the Unix/Linux world. Some of these libraries have been ported on across platforms (example: PDCurses)

For very simple things such as a progress bar or a counter, and as long as you remain on a single line there is the trick of using "\r" (carriage return) in the output, to place the cursor back at the begin of the current line. Example:

for (int i = 0; i < 100; i++) {
    cout << "\rProgress: " << setw(3) << i;
    this_thread::sleep_for(chrono::milliseconds(100));
}

Upvotes: 5

Droideka
Droideka

Reputation: 41

I'm not sure to understand you completely but with creating an array of 100 elements of type char you can modify any position of the array and loop it with a std:cout to mostrate it on the console. Perhaps could be better define the array of 50 chars to resuce the size of the printed result.

For example, if you have to print a progessbar in the 1% process, you should print:

Char progressbar[100] = {'X','','','','','','','','',........}

Upvotes: -2

Related Questions