Dori
Dori

Reputation: 1055

Linux terminal: carriage return stuck at line wrap

I have c++ code running on a remote Linux server, accessed via MobaXterm. The process takes a while and is multithreaded, so I've added a progress printing mechanism that looks like this:

void update_progress() {
    omp_set_lock(&lock);
    string progress = get_threads_progress();
    cout << "\rProgress " << progress;
    omp_unset_lock(&lock);
}

With three threads, it could look something like this:

Progress | 23/100 | 42/100 | 89/200

The carriage return is there so I can see the job's progress on a single line. The problems start when running my code on a 48-core machine: the progress string is too long for the terminal, the line wraps around and the carriage return only sets the cursor back to the beginning of the current line. For example:

// Several threads run this in parallel
for (int i=1; i<=5; ++i) {
    update_progress();
}

I'll get something like the following output:

Progress | 23/100 | 41/100 | 86/100 | 19/100 | 3/100 | 97/100 | 54/1 
Progress | 23/100 | 42/100 | 86/100 | 19/100 | 3/100 | 97/100 | 54/1 
Progress | 23/100 | 42/100 | 86/100 | 20/100 | 3/100 | 97/100 | 54/1 
Progress | 23/100 | 42/100 | 87/100 | 20/100 | 3/100 | 97/100 | 54/1 
00 | 23/100 | 21/100

I was under the assumption that the carriage return \r should successfully place the cursor back at the P in Progress, regardless of the terminal width...

Am I wrong? If so, how (if possible) can I get what I want? If not, what's the issue?

Upvotes: 2

Views: 896

Answers (2)

Hristo Iliev
Hristo Iliev

Reputation: 74495

In Putty it is possible to switch off the automatic wrap mode:

Settings -> Terminal -> [ ] Auto wrap mode initially on

The setting is on by default. Switching it off disables the automatic wrap and instead keeps the lines unbroken. It also means though that you only see from each long line as many symbols as the window width permits. Therefore, a pager with support for horizontal scrolling, e.g., less, is required to view text with long lines.

Or run your program in a GNU screen session and use Ctrla:wrap to toggle the wrap mode.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409482

The carriage-return is not handled in your program or by the standard library, but by the terminal program that displays the text. And it only goes to the beginning of the current line, the line on which the cursor currently is, which if there is a wrap is not the start of the previous line. So make sure the text you print is simply not long enough to cause wrapping.

Upvotes: 4

Related Questions