How to update a output field in terminal without output a new line? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to update a printed message in terminal without reprinting (Linux)
I have c++ code, performing some simulations.
I want to show the percentage of my simulation, but I don't want to output a new line every step, like
%1
%2
%3
...
Is there a way, in c++ or in shell scripts to show the progress without creating new lines?
Thanks
Edit 1
Anyone know how to update a number on my personal webpage without refreshing the whole page?
Thanks
Edit 2
double N=0;
forAll (internalIDs_, i) {
N++;
double percent = 100*N/internalIDs_.size();
// Info<< "\rProgress: " << percent << "%" << endl;
printf("\r[%6.4f%%]",percent);}
The terminal cursor keeps blinking cyclically through the numbers, very annoything, how to get rid of this?

The trick used for this is to return to the first position in the current line instead of progressing to the next line.
This is done by writing the \r character (carriage return) to the terminal/stdout.

cout << "\r%1";
cout << "\r%2";
cout << "\r%3";
...
\r - move at the begin of line;
but!
if :
cout << "\rsomelongmessage";
cout << "\rshort";
then you get at out:
shortongmessage
because of:
somelongmessage
^^^^^
short
but you can:
cout << "\rsomelongmessage";
cout << "\rshort ";
then you get finally:
short

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.

How to continue to execute the C++ code after gnuplot was called? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am using gcc as a compiler and gnuplot-iostream.h as a stream to combine C++ code and the gnuplot features.
What I am doing:
I try to make a fit of the data via gnuplot and extract the final fit parameters from the generated fit.log file for further processing.
What's the problem:
When executing the code like this
std::cout << "Starting to fit" << std::endl;
if (bStartFit == true)
{
// gp << doing stuf here;
std::cout << "Test end" << std::endl;
}
std::cout << "Fit is done" << std::endl;
the output will be:
Starting to fit
Fit is done
Test end
//gnuplot stuff
My question is: how to force the code execute gnuplot stuff exactly when needed, and after proceed with the C++ code. For example:
write intro message;
plot the sin(x) function (as fast example);
wait until the gnuplot is closed;
write exiting message or do what ever AFTER the gnuplot is done.
thank you,
P
EDIT:
std::string filename = "fit.log";
if (bStartFit == true)
{
// Using Gnuplot for the data fit (command are parsed as the strings):
// 1. define the fit function.
gp << "f(x) = imfpZP * x**(-b) + c * x**(d) + g * x**(h) \n";
// 2. fit parameters first assumption.
gp << "b = 1.1; c = 0.5; d = 1.0; g = 2.0; h = 0.1 \n";
// 3. fit range.
gp << "fit [50:10000] f(x) 'agn.iimfp' via b,c,d,g,h \n";
// 4. set the logarithmic scale.
gp << "set logscale \n";
// 5. plot the fitted data.
gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' \n";
std::cout << "Fit was successful" << std::endl;
}
// Opening the generated fit.log file to store the fit parameters:
std::ifstream inFIT(filename.c_str());
if (inFIT.is_open())
{
std::cout << "FIT log is opened" << std::endl;
std::string line;
int lineCounter = 0;
while (std::getline(inFIT, line))
{
lineCounter++;
}
std::cout << "Total lines: " << lineCounter << std::endl;
// Getting the five lines with fit parameters from the fit.log:
std::fstream& GoToLine(std::fstream& file, unsigned int lineNumber);
std::fstream file(filename.c_str());
GoToLine(file, lineCounter - 15);
std::string b_Line;
std::getline(file, b_Line);
std::cout << b_Line << std::endl;
std::istringstream sb(b_Line);
std::string tempStr;
char tempChar;
sb >> tempStr >> tempChar >> b
// similar code to get another 4 lines
;
It is operating system specific. I am guessing you are on Linux (or at least on some POSIX OS). Then you really should read Advanced Linux Programming. And using strace(1) could be helpful to understand what is happening.
You could use popen(3), but you probably should explicitly use system calls (they are listed in syscalls(2)) like pipe(2), fork(2), dup2(2), execve(2), waitpid(2), etc. And very probably have some event loop (e.g. around poll(2)).
BTW, you should be aware that input output is buffered, and you probably want to be sure that your gnuplot stream is regularly flushed (so use std::endl or std::flush appropriately on it). Writing a \n is not enough! You probably should code at least
gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' "
<< std::endl;
(I have replaced some \n inside a string with an explicit use of std::endl)
I don't know much about gnuplot stream (I'm guessing it is a bit like some specialized popen but using C++ streams), but I guess that you should the gnuplot print or printerr command to communicate to your calling program the fact that a given curve has been plotted. (But then you need a genuine event loop, and you are defining a bidirectional protocol between gnuplot and your program.).
Perhaps Qt or POCO might be relevant, because they provide some notion of event loop and processes. Perhaps you might have several threads (one managing gnuplot and the other for the rest), but then you have synchronization issues.
(I don't understand enough what your program is supposed to do, and how you have coded it, so it is a blind guess; I feel your question is very unclear)
Read more about Inter-Process Communications.

sf::String put into std::map key doesn't work - the vaule is not saved into map [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
as I wrote in the topic - I try to put sf::String into map first argument and it does not work. Here's the code:
void Flashcards::add(sf::String sf_string) {
std::string text = sf_string.toAnsiString();
std::pair<std::string,std::string> pairr = std::make_pair(text,"<Polish translation>");
std::cout << "Inserting: " << pairr.first << std::endl;
all_words.insert(pairr); //std::map<std::string, std::string> variable
void Flashcards::show() {
std::cout << "Flashcards:\n";
for (std::map<std::string, std::string>::iterator it = all_words.begin(); it != all_words.end(); it++)
{
std::cout << "English word: " << it->first
<< " " << "Polish word: " << it->second << std::endl;
}
The result in console is:
Inserting: //a word//
Flashcards:
Polish word: <Polish translation>
Instead of needed:
Inserting: hello
Flashcards:
English word: //a word// Polish word: <Polish translation>
Here are the variations I have already tried:
1) I switched the arguments so it looked like this: std::make_pair("<Polish translation>",text); and it works - hardcoded key and the value are both showed in the console (but I don't want hardcoding, what is obvious).
2) Note that this line: std::cout << "Inserting: " << pairr.first << std::endl; shows that the key value is converted into std::string correctly - calling this will show value we have just typed on the keyboard.
3) I tried to send the sf::String value directly to the std::make_pair() method, it works exactly the same as putting std::string there.
Can somebody say how to make this work?
The string you are providing as an argument to the add method obviously ends with a \r (carriage return) character, probably because you are reading it from a Windows text file using a Unix/Linux execution environment. If you capture the output of your program in a file and look at it with a hexdumper (such as hd), you should immediately see what is going on.
It certainly has nothing to do with your use of the C++ standard library. However, you don't need to go to all that work to insert an entry into a std::map. Just do this:
all_words[key] = value;
As long as key has the right type (or there is an automatic conversion), that will do precisely what you want in a single line easily-understood line, and probably more efficiently as well.

C++ cout overwriting itself while in for loop

The cout statement in this for loop:
for (vector<Student>::iterator qw = students.begin(); qw != students.end(); ++qw){
Student a = *qw;
name = a.getName();
regno = a.getRegNo();
std::cout << "Name: "<< name << " Reg Number: " << regno << endl;
}
Is creating some odd behavior, what the cout should print is something like this:
Name: Mike Sanderson Reg Number: 10101
However which it actually prints out it:
Reg Number: 10101on
It would seem to me that after the second part of the cout statement it is going back to the start of the line and overwriting itself, but why?
Hope you guys can help me and if you need more info let me know!
This is what the carriage return character does (that is, \r in a string literal). I assume name string has an \r at the end of it. You'll need to figure out how it got there and remove it.
I'm guessing that perhaps you read the names from a file, and that file was created on Windows, which ends lines with \r\n by default. C++ will usually handle the conversion between line endings for you when reading from a text file, but if you're reading the file as a binary file and using \n as a delimiter, you'll have this problem. The \r will be read as though it were part of the line.

Compiler throws cout'ing out of loop

I wrote a numerical simulation and, as a tweak, I wanted to add some basic progress bar.
In the main loop I wrote:
if(particles.t>=pr*maxtime){
cout << "|";
pr+=0.01;
}
Where pr starts at 0.01. So, basically it was supposed to cout one hundred "|" during the computation. Instead of that it couts these "|" at the end of the simulation, all at once.
And when I modify this code to:
if(particles.t>=pr*maxtime){
cout << pr << "\n";
pr+=0.01;
}
it works as it should.
I guess it have something to do with optimization, I am compiling my code using g++, with options -Wall and -lm. Code like this worked when I wrote it in C#, a while ago.
The problem is with the buffering of the output. Place cout.flush(); after each printing and the issue should be solved.
The writes to cout (and many other streams) are buffered. If you want to make them immediately visible, you need to flush the stream:
if(particles.t>=pr*maxtime){
cout << "|";
cout.flush();
pr+=0.01;
}