Clearing terminal in Linux with C++ code - c++

Okay, I have been researching on how to do this, but say I am running a program that has a whole bit of output on the terminal, how would I clear the screen from within my program so that I can keep my program running?
I know I can just type clear in terminal and it clears it fine, but like I said, for this program it would be more beneficial for me.
I found something that works, however, I'm not sure what it is or what it is doing.
cout << "\033[2J\033[1;1H";
That works but I have no clue what it is, if you could explain it, than I would much appreciate it.

These are ANSI escape codes. The first one (\033[2J) clears the entire screen (J) from top to bottom (2). The second code (\033[1;1H) positions the cursor at row 1, column 1.
All ANSI escapes begin with the sequence ESC[, have zero or more parameters delimited by ;, and end with a command letter (J and H in your case). \033 is the C-style octal sequence for the escape character.
See here for the full roadshow.

Instead of depending on specific escape sequences that may break in unexpected situations (though accepting that trade-off is fine, if it's what you want), you can just do the same thing you'd do at your shell:
std::system("clear");
Though generally system() is to be avoided, for a user-interactive program neither the extra shell parsing nor process overhead is significant. There's no problem with shell escaping either, in this case.
You could always fork/exec to call clear if you did want to avoid system(). If you're already using [n]curses or another terminal library, use that.

For portability you should get the string from termcap's cl (clear) capability (Clear screen and cursor home). (Or use std::system("clear") as told by Roger Pate).
man 3 termcap (in ncurses)
man 5 termcap
set | grep TERMCAP

you can write in a terminal "clear > data" and read in data the escapes sequance
0x1B[H0x1B[2J0x1B[3J
so
std::cout << "\033[H\033[2J\033[3J" ;

Related

C++ Error-code <U+0013>

I have a function in C++ that I am testing, and after careful inspection I'm pretty sure everything is correct. However, I'm still getting a mysterious error relating to the "return" statement at the end of the function.
Where "population" is a real matrix (using the armadillo matrix package).
Looks like the error code represents a Unicode value. Check if the file is clean of characters which shouldn't be there (copy paste into notepad and then copy paste back).
You have accidentally managed to enter the Device Control 3 character (which has the unicode value U+0031) before return and after ;. The character is probably invisible for you, which is why you aren't seeing anything.
Replace those with spaces. You can probably turn your editor into some kind of "show invisibles" mode which might help.
If you are used to using Emacs keybindings and tried to Cx-s Cx-c to save and quit in another IDE ie Xcode it will insert odd unicode characters.

Scrolling character letter in C++

I am building a part of a tower defense game in a strictly console environment and i am stuck at the moving of a creature lets say "c", i would like the letter "c" to start on the left and move a space at a time to the right on the same line basically:
c (one second later)
c (one second later)
c and so on....
i thought that this could be implimented with an array but am lost, i want to be able to use simple code, not weird libraries and weird methods, just simple as possible. Thank you
One method is display all the characters, then a carriage return ('\r') and then reprint the line.
This allows you to "walk" characters across. This will only work on video terminals that do not advance a line upon receiving a CR.
Another method would be to print 10 backspace characters, a space, then your 10 'c'. This may not be as fast as the carriage return method above, but worth looking at.
As others have said, you may want to look into a terminal library such as ncurses. The library allows you to position the cursor on the screen, based on the terminal type. This may require setting up the console window to emulate a terminal.

Linux Printing - How To

I find it hard to explain but I will try my best. Some times in Linux- in the Terminal- things get printed but you can still write over them. eg when using wget you get a progress bar like this:
[===================> ]
Now if you type something while it is doing this it will 'overwrite' it. My question is how to recreate this in c++.
Will you use something like
cout <<
or something else?
I hope you understand what I am getting at...
btw I am using the most recent version of Arch with xfce4
Printing a carriage return character \r is typically interpreted in Linux as returning you to the beginning of the line. Try this, for example:
std::cout << "Hello\rJ";
The output will be:
Jello
This does depend on your terminal, however, so you should look up the meaning of particular control characters for your terminal.
For a more cross-platform solution and the ability to do more complex text-based user interfaces, take a look at ncurses.
You can print the special character \b to go back one space. Then you can print a space to blank it out, or another character to overwrite what was there. You can also use \r to return to the beginning of the current output line and write again from there.
Controlling the terminal involved sending various escape sequences to it, in order to move the cursor around and such.
http://www.ibiblio.org/pub/historic-linux/ftp-archives/tsx-11.mit.edu/Oct-07-1996/info/vt102.codes
You could also use ncurses to do this.

C++ standard output format

I want to create a C++ console application that print some text to different parts of the console. For example in QBasic you can use:
locate(8,5)
print "hi"
And hi would be printed in column 8 line 5. In C++ when I use cout it always prints on the next line, and begins printing in the first column.
Is there any way I can do this?
C++ itself does not have this feature, it's I/O model is a fairly simple, sequential one.
If you want to do fancy cursor positioning, you'll need to output (for example) control characters which your terminal will recognise as special commands (such as ANSI or VT escape sequences), or use a library like curses (see ncurses here) which can do a lot of the grunt work for you, not just cursor positioning but also things like text mode windows and so forth.
A library, like ncurses can help you do this.

Bash reg-exp substitution

Is there a way to run a regexp-string replace on the current line in the bash?
I find myself rather often in the situation, where I have typed a long commandline and then realize, that I would like to change a word somewhere in the line.
My current approach is to finish the line, press Ctrl+A (to get to the start of the line), insert a # (to comment out the line), press enter and then use the ^oldword^newword syntax (^oldword^newword executes the previous command after substituting oldword by newword).
But there has to be a better (faster) way to achieve this. (The mouse is not possible, since I am in an ssh-sessions most of the time).
Probably there is some emacs-like key-command for this, that I don't know about.
Edit: I have tried using vi-mode. Something strange happened. Although I am a loving vim-user, I had serious trouble using my beloved bash. All those finger-movements, that have been burned into my subconscious suddenly stopped working. I quickly returned to emacs-mode and considered, giving emacs a try as my favorite editor (although I guess, the same thing might happen again).
in ksh, in vi mode, if you hit 'v' while in command mode it will spawn a full vi session on the contents of your current command line. You can then edit using the full range of vi commands (global search and replace in your case). When :wq from vi, the edited command is executed. I'm sure something similar exists for bash. Since bash tends to extend its predecessors, there's probably something similar.
G'day,
What about using vi mode instead? Just enter set -o vi
Then you can go to the word you want to change and just do a cw or cW depending on what's in the word?
Oops, forgot to add you enter a ESC k to o to the previous line in the command history.
What do you normally use for an editor?
cheers,
Rob
Edit: What I forgot to say in my original reply was that you need to think of the vi command line in bash using the commands you enter when you are in "ex" mode in vi, i.e. after you've entered the colon.
Worst thing is that you need to move around through your command history using the ancient vi commands of h (to the left) and l (to the right). You can use w (or W) to bounce across words though.
Once you get used to it though, you have all sorts of commands available, e.g. entering ESC / my_command will look back through you r history, most recent first, to find the first occurrance of the command line containing the text my_command. Once it has found that, you can then use n to find the next occurrance, etc. And N to reverse the direction of the search.
I'd go have a read of the man page for bash to see what's available under vi mode. Once you get over the fact that up-arrow and down-arrow are replaced by ESC k, and then j, you'll see that vi mode offers more than emacs mode for command line editing in bash.
IMHO natchurly! (-:
Emacs? Eighty megs and constantly swapping!
cheers,
Rob
Unfortunately, no, there's not really a better way. If you're just tired of making the keystrokes, you can use macros to trim them down. Add the following to your ~/.inputrc:
"\C-x6": "\C-a#\C-m^"
"\C-x7": "\C-m\C-P\C-a\C-d\C-m"
Now, in a new bash instance (or after reloading .inputrc in your current shell by pressing C-x C-r), you can do the following:
Type a bogus command (e.g., ls abcxyz).
Press Ctrl-x, then 6. The macro inserts a # at the beginning of the line, executes the commented line, and types your first ^.
Type your correction (e.g., xyz^def).
Press Ctrl-x, then 7. The macro completes your substitution, then goes up to the previous (commented) line, removes the comment character, and executes it again.
It's not exactly elegant, but I think it's the best you're going to get with readline.