How to update portions of output in C++? - c++

So I want to update some numbers in lines of code without reprinting them, for instance, some percentages. Fortunately, I've got a bit of help using \r carriage return, but the thing is that I want to use this on new lines and this ain't working with \n or std::endl
Example:
int gameTime = 0;
do
{
\\ I need a new line after the below one
printf("%d'\r", gameTime);
std::cout << "\nattempt";
Sleep(450);
gameTime++;
} while (gameTime <= 90);

Both windows and linux support these escape codes:
https://www.csie.ntu.edu.tw/~r92094/c++/VT100.html
Where that page says ^[, you should insert \033.

Related

Is it possible to print this shape without printing spaces in C++ as described in the book "Think Like Programmer" by Anton Spraul?

In a book named "Think Like a Programmer" by Anton Spraul, on chapter 2, exercise 1, page 53, this is what is written:
Using the same rule as the shapes programs from earlier in the chapter
(only two output statements — one that outputs the hash mark and one
that outputs an end-of-line), write a program that produces the
following shape:
########
######
####
##
So we can only use cout << "\n"; and cout << "#"; but not cout << " ";
Solving this problem by printing spaces is easy (see code below). But is it possible to print such shape without printing spaces in C++?
#include <iostream>
using std::cin;
using std::cout;
int main()
{
int shapeWidth = 8;
for (int row = 0; row < 4; row++) {
for(int spaceNum = 0; spaceNum < row; spaceNum++) {
cout << " ";
}
for(int hashNum = 0; hashNum < shapeWidth-2*row; hashNum++) {
cout << "#";
}
cout << "\n";
}
}
Solving this problem by printing spaces is easy (see code above). But is it possible to print such shape without printing spaces in C++?
In one of the answers I read one can remove the for (int spaceNum. . . loop and rather just put cout << setw(row+1); to achieve that.
Clarification: The author never used a shape as example where one had to print spaces or indentations like the above. Interpreting the exercise above literally, he expects us to write that shape by printing "#" and "\n" only. Printing spaces or indentations by only printing "#" and "\n" seems not possible to me, so I thought maybe he was not careful when he wrote exercises. Or there's a way to achieve that but it's just me who doesn't know. This is why I asked this.
Yes, this is possible.
Set the stream width to the length of the row.
Set the stream formatting to right-justified.
Look up stream manipulators in your book or another C++ references.
Possibly! But that is a question about the system you’re running on, not about C++. As far as the language is concerned, it’s just outputting characters. The fact that outputting a “space” character moves the cursor to the right on the screen — or even the existence of the screen — is a matter of how the operating system and the software running on it interpret the characters that have been output.
Most notably, you can use ANSI escape sequences to move the cursor around on most text consoles. There’s no particular reason to do this unless you’re writing a full-screen text mode UI.

Why is this string being overwritten instead of being concatenated?

I'm just writing a little script to create some fake discord names.
To do this, I took a couple of .csv files with adjectives and nouns, imported them into vectors, and concatenated them. Ex:
vector<string> noun;
vector<string> adj;
infile.open("english-adjectives.txt");
while(infile.good()){
getline(infile,x);
adj.push_back(x);
}
infile.close();
shuffle(begin(adj), end(adj), rng);
I did the same thing for nouns, and then tried to concatenate them with a number, but I got a really weird result.
for (unsigned int i = 0; i < adj.size(); i++){
string temp;
temp.append(adj[i]);
temp.append(noun[i]);
discord.push_back(temp);
}
for (unsigned int i = 0; i < discord.size(); i++){
cout << discord[i] << "#0001" << "\n";
}
output:
#0001icresearch
#0001downstairs
#0001edfiddle
When I remove the "#0001" part, it prints just fine.
honoredfiddle
wanderby
deliciousofficial
Any ideas on why this is happening? I checked the newline chars in all my .csv files, and it's formatted for Unix, so I have no idea why this is happening.
Answer from Jerry Jeremiah's comment
Your CSV file was made on Windows and has Windows line endings. But
yhe computer you are running this on uses UNIX style line endings so
each line in the CSV has a \r at the end that is not being removed.
There are multiple ways of removing the \r from the CSV file - or you
could even do it inside this program after reading the data.
Took it into notepad++, edited the newlines to be just LF, and that fixed it.

Formatting Output c++

Wanting to do some fancy formatting. I have several lines that I want to interact with each other. Get the first two lines. Print out the character in the second line times the integer in the first line. Seperate them all with a asterisk character. No asterisk after the final character is printed. Move onto the next integer and character. Print them on a separate line. Do this for the whole list. The problem I am having is printing them on separate lines. Example:
5
!
2
?
3
#
Desired output:
!*!*!*!*!
?*?
#*#*#
My output:
!*!*!*!*!*?*?*#*#*#*
Below is my code. Another thing to mention is that I am reading the data about the characters and numbers from a separate text file. So I am using the getline function.
Here is a chunk of the code:
ifstream File
File.open("NumbersAndCharacters.txt")
string Number;
string Character;
while(!File.eof(){
getline(File, Number);
getline(File, Character);
//a few lines of stringstream action
for (int i=0; i<=Number; i++){
cout<<Character<<"*";}//end for. I think this is where
//the problem is.
}//end while
File.close();
return 0;
Where is the error? Is it the loop? Or do I not understand getline?
It should be printing an "endl" or "\n" after each multiplication of the character is done.
Thanks to everyone for the responses!
You have not shown your code yet, but what seems to be the issue here is that you simply forgot to add a new line every time you print your characters. For example, you probably have done:
std::cout << "!";
Well, in this context you forgot to add the new line ('\n'), so you have two options here: first insert the new line yourself:
std::cout << "! \n";
Or std::endl;
std::cout << "!" << std::endl;
For comparison of the two, see here and here. Without further description, or more importantly your code that doesn't seem to work properly, we can't make suggestions or solve your problem.

Space vs null character

In C++, when we need to print a single space, we may do the following:
cout << ' ';
Or we can even use a converted ASCII code for space:
cout << static_cast<char>(32); //ASCII code 32 maps to a single space
I realized that, printing a null character will also cause a single space to be printed.
cout << static_cast<char>(0); //ASCII code 0 maps to a null character
So my question is: Is it universal to all C++ compilers that when I print static_cast<char>(0), it will always appear as a single space in the display?
If it is universal, does it applies to text files when I use file output stream?
No, it will be a zero(0) character in every compiler. Seems that the font you use renders zero characters as a space. For example, in the old times, DOS had a different image (an almost filled rectangle) for zero characters.
Anyway, you really should not output zero characters instead of spaces!
As for the text file part: open the outputted file using a hex editor to see the actual bits written. You will see the difference there!
On my computer, this code
#include <iostream>
int main() {
std::cout << "Hello" << static_cast<char>(0) << "world\n";
}
outputs this:
Helloworld
So no, it clearly doesn’t work.

How to update a printed message in terminal without reprinting

I want to make a progress bar for my terminal application that would work something like:
[XXXXXXX ]
which would give a visual indication of how much time there is left before the process completes.
I know I can do something like printing more and more X's by adding them to the string and then simply printf, but that would look like:
[XXXXXXX ]
[XXXXXXXX ]
[XXXXXXXXX ]
[XXXXXXXXXX ]
or something like that (obviously you can play with the spacing.) But this is not visually aesthetic. Is there a way to update the printed text in a terminal with new text without reprinting? This is all under linux, c++.
try using \r instead of \n when printing the new "version".
for(int i=0;i<=100;++i) printf("\r[%3d%%]",i);
printf("\n");
I'd say that a library like ncurses would be used to such things. curses helps move the cursor around the screen and draw text and such.
NCurses
Something like this:
std::stringstream out;
for (int i = 0; i< 10; i++)
{
out << "X";
cout << "\r" << "[" << out.str() << "]";
}
The sneaky bit is the carriage return character "\r" which causes the cursor to move to the start of the line without going down to the next line.
Others have already pointed out that you can use \r to go back to the beginning of the current line, and overwrite the entire line.
Another possibility is to use the backspace character ("\b") to erase a few spaces, and overwrite only those spaces. This can have a couple of advantages. First, it obviously avoids having to regenerate everything in the line, which can sometimes be mildly painful (though that is fairly unusual). Second, it can avoid some pain in displaying data that (for one example) shrinks in size as you write it -- for example, if you're displaying a count-down from 100 to 0, with \r you have to be careful about overwriting the entire previous length, or your countdown will go from (for example) 100 to 990 (i.e., leaving the previous "0" intact).
Note, however, that while back-space within a line normally works, a backspace at the beginning of a line may or may not move the cursor/write position back to a previous line. For most practical purposes, you can only move around within a single line.
'\r' will perform a carriage return. Imagine a printer doing a carriage return without a linefeed ('\n'). This will return the writing point back to the start of the line... then reprint your updated status on top of the original line.
It's a different language, but this question might be of assistance to you. Basically, the escape character \r (carriage Return, as opposed to \n Newline) moves you back to the beginning of your current printed line so you can overwrite what you've already printed.
Another option is to simply print one character at a time. Typically, stdout is line buffered, so you'll need to call fflush(stdout) --
for(int i = 0; i < 50; ++i) {
putchar('X'); fflush(stdout);
/* do some stuff here */
}
putchar('\n');
But this doesn't have the nice terminating "]" that indicates completion.
I've written this loading bar utility some time ago. Might be useful...
https://github.com/BlaDrzz/CppUtility/tree/master/LoadingBar
You can customise basically anything in here.
int max = 1000;
LoadingBar* lb = new LoadingBar(10, 0, max);
for (size_t i = 0; i <= max; i++)
{
lb->print();
lb->iterate();
}
cout << lb->toString() << endl;
Very simple and customisable implementation..