Overwrite text written to console - c++

I want to achieve the following:
I have a program which generates files, and it should print a warning if the file with the given name already exists, asking the user if it should be overridden. It looks like the following:
Processing file test.sdf
Checking SDF file... [OK]
Parsing SDF... [OK]
Generating NDDL model file... [WARN]
Warning. The file "/home/chris/models/test-model.nddl" already exists. Overwrite? [y/N]
Now, if the user decides what to do, I want to rewind the console cursor to the [ character of [WARN], and overwrite it with [OK] or [FAIL], and then overwrite the following lines with the next outputs of the program.
I found that I could achieve this with ANSI control sequences. Since I am just using Ubuntu I'm okay with that.
I came up with two ideas:
1) Rewind the cursor until I find the string [WARN] and then begin to write again.
2) Move the cursor up line by line until the line Generating NDDL model file... [WARN] is removed, and overwrite it with for example Generating NDDL model file... [FAIL].
But with both approaches I have a problem which I just cannot solve or find a way googling...
Problem with 1): I can't figure out how to read the character at the current cursor position. But anyway, I don't think that this would be a good idea. It just doesn't seem to be reliable.
Problem with 2): Since the path of the input file can be arbitrary, I have no control over the amount of lines which have been printed after the [WARN] appears, so I just don't know how much std::cout << "\033[F" << "\033[2K" << std::flush; I should run (ANSI Control Sequences for move-cursor-one-line-up and clear-all-contents-in-line). Also, I don't know how big the width of the terminal window is, so I can't calculate it either (no idea if this would be a good idea though...)
I am sure that there must be a way to achieve this, but I just can't figure out a good and reliable way to do so...
Does anybody of you got an idea? I appreciate every kind of help

X/Y Problem
If you insist on manipulating the console directly, then why not just back over the entire last two lines completely? Why try and edit a line when you can just reprint the entire thing. Also you are not guaranteed to be able to manipulate every console the same way between platform and shells.
You are printing the lines out you should easily know how many to back up and overwrite. If you can't do that, just clear the screen and write everything back out again.
Solution
The correct way to present an interface like this is with acurses library ( or equivalent ) and control the output to the console completely. That gives you complete control.
If you think this is overkill then you are just doomed to recreate the functionality of curses a bit of a time and end up with a mess at the end.

Well, there are some possibilites using the carriage return (\r), which will take you to the start of the current line, or by using the backspace (\b), which will rewind one character position and then you just have to write all over again. No curses. No ANSI crazyness.

Related

Output is more extensive than Results window can remember so log capturing forgets to record

I have an extensive Stata do-file that runs with no issues, but there is too much output to be all captured in the results window. I read up on log files to create a capture of the output, which works. This is the code I have at the beginning of my do-file:
______________________________________________*/
capture log close
clear
*------------------------------------------------------------------------------------------------------------------
*SET THIS TO USE THE CORRECT DIRECTORY
local thisdir "C:\Users\my computer file"
*------------------------------------------------------------------------------------------------------------------
cd "`thisdir'"
log using "STATAlogfile.txt", text append
The do file then runs successfully until the end where I have a log close and then get the output in the results window:
.
. log close
no log file open
r(606);
end of do-file
r(606);
The log txt file when I look at it then only captures a small amount of the do-file (I assume as far as what can be fit within the memory of the Results window).
I was wondering how I can fix this: is it as simple as sticking in a bunch of log appends in the middle of my do-file to capture everything, or is there a different command that will make sure it continues throughout the whole do-file?
I don't follow the assertions in the post title or body.
There is no sense in which the code "forgets" to do anything. It seems that it is you, the programmer, who forgot to include log commands where you now realise you needed them. That could happen to any experienced programmer too.
What goes in a log file is nothing to do with what is visible at any one time in the Results window. A log file is unlimited in size, subject to your computer memory.
If you can't copy and paste results retrospectively, then the only work-around is to fix your do-file code and run it again.
I think what underlies your question is a verbal misunderstanding of capture. capture as a Stata command is about eating an error if the following command fails. That is, capture ensures that Stata carries on when otherwise it would stop with an error message. It has nothing to do with capturing, in the sense of catching and recording, your output.
Spelling is Stata, not STATA, and has been since about 1985.

How to draw to a certain part of the console/terminal?

I'm curious to know how you can draw/update a certain region of the terminal/console. Is there any cross-platform libraries to do so?
The reason I want to know is because I am developing an instant message command line application, and I was curious to know how I can update the message viewer (where all the messages go) separately to where you write commands/text for other people in the chat. Obviously if I just tried to get input and write to cout then the input the user is entering and the messages would be "interfered" (by interfered I mean split in multiple lines).
I was thinking of using two stream objects: one to store the view (messages/output from the server) and one to store the input from the user, and just redraw whenever required. However, this seems inefficient and it requires me to clear the screen (in which case I don't know how to clear the screen efficiently and in a cross-platform manner).
I was also thinking of just switching to Qt/wxWidgets as it might simpler to make a GUI.
Use ncurses library to write text-based user interfaces in a terminal-independent manner.
As suggested by #Naruto, ncurses is a good way to go. At a much more basic level, you can also just use ANSI escape codes to move the cursor around the screen too:
For example, to position the cursor at line 5, column 23, you can enter this
echo -n "\033[5;23H"
There are more examples here.

Importing from .txt and converting to hexadecimal then exporting and vice versa C++

This is my first project, I'm trying to teach myself so please bear with me and don't assume anything about my knowledge of programming.
What I want to do is create a console program that will take file, Text.txt, in this instance, read it, turn the ASCII it into hexadecimal and then overwrite the Text.txt file with the hex code, and if run again, will reverse the process.
Is there a way to do this on a command basis so that I have to type something, lets say "Start" into the console before it will actually initialize this process? And on top of that, keep the console open so I could type "Start" (or another word, if this is impossible) and have it undo the process?
I currently have this tacked onto the end to keep the program open, but how would I use it when doing what I wish to do as mentioned above? Or is there a better method?
[code]
std::string in;
while ((std::cin >> in) && (in != "exit"))
{
}
return 0;
}
I know I need to use fstream in order to import and export but I'm not sure how to do it without closing everything immediately after it has finished or how to tie it in to make it convert the hexadecimal/ASCII first.
Thanks for any help or tips you can give.
Edit: Sorry, my question is:
What is the basic process for turning the ASCII in the Text.txt file into hex and then exporting it?
I have a basic understanding of the fstream concept on its own but I'm not really sure how to implement it along with the conversion of the text, and I don't really know where to start on exactly how to convert the text into hex.
You've got several questions bundled here, and I think you might just be overwhelmed.
Is there a way to do this on a command basis so that I have to type something
How would I use it when doing what I wish to do as mentioned above?
but I'm not sure how to do it without closing everything immediately after it has finished
how to tie it in to make it convert the hexadecimal/ASCII first.
Start by decomposing the problem into parts, and implement each, one at a time. First: file I/O -- create a function (or better still: a class) which reads from a file.
Next: add a function or method that convert values from ASCII to hexadecimal.
Next: add a class or function which implements the terminal control features/curses/etc.
Separate these and they'll be easier to design, easier to test, and easier to get help from SO.

Remove A Line Of Text With Filestreams (C++)

I have a large text file.
Each time my program runs, it needs to read in the first line, remove it, and put that data back into the bottom of the file.
Is there a way to accomplish this task without having to read in every part of the file?
It would be great to follow this example of pseudo code:
1. Open file stream for reading/writing
2. data = first line of file
3. remove first line from file <-- can I do this?
4. Close file stream
5. Open file stream for appending
6. write data to file
7. Close file stream
The reason I'm trying to avoid reading everything in is because the program runs at a specific time each day. I don't want the delay to be longer each time the file gets bigger.
All the solutions I've found require that the program process the whole file. If C++ filestreams are not able to accomplish this, I'm up for whatever alternative is quick and efficient for my C++ program to execute.
thanks.
The unfortunate truth is that no filesystem on a modern OS is designed to do this. The only way to remove something from the beginning of a file is to copy the contents to a new file, except for the first bit. There's simply no way to do precisely what you want to do.
But hopefully you can do a bit of redesign. Maybe each entry could be a record in a database -- then the reordering can be done very efficiently. Or perhaps the file could contain fixed-size records, and you could use a second file of indexes to specify record order, so that rearranging the file was just a matter of updating the indices.

How to get text to not scroll in a terminal

I am trying to write a C++ program where the screen updates every 1 second. However, I want the screen to be similar to htop, where it updates and does not have to scroll with each update. That way, I don't have a step-by-step iteration in my terminal.
Does anyone know what this style is called or how to program it?
Thanks!
The usual way is with something like ncurses. If you're on Windows, it has console functions built in so you can do the same without any extra libraries (though they do take a while to understand). If you only want one line of output, you can use a '\r' to return to the beginning of the current line and/or \b to backspace over previous characters (handy if yoy only want to overwrite a few little bits and pieces).
You'll need a library like curses (on *nix) or pdcurses for Windows (conio functions would probably still work on windows).