How to remove a line from std::cout in C++? - c++

I want to write a timer program which shows the time from x seconds to 0 seconds, for example, if x=10s: 10s - 9s - 8s ... 1s. Yet, I want to erase the previous time each second: when the program writes "9s" in cout I want to erase "10s". Do you know how to erase the previous line wrote in std::cout ? I'm on linux but I'd want the code to be portable if that may be possible.
I tried std::cout << "\r"; but it didn't work, for example, whit a ten seconds timer, the program waits ten seconds and then writes "1s".
Here my code:
#include <iostream>
#include <thread>
#include <chrono>
std::string convert(unsigned short int seconds);
int main()
{
unsigned short int seconds {};
std::cout << "Entrez le temps en secondes du minuteur : ";
std::cin >> seconds;
std::cout << std::endl;
for (unsigned short int i {seconds}; i != 0; i--)
{
std::string time {convert(i)};
std::cout << '\r' << time ;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
std::string convert(unsigned short int seconds)
{
if (seconds < 60)
return std::to_string(seconds) + "s";
else if (seconds >= 60 && seconds < 3600)
return std::to_string(seconds/60) + "min " + std::to_string(seconds%60) + "s";
else
return std::to_string(seconds/3600) + "h " + std::to_string((seconds%3600)/60) + "min " + std::to_string(seconds%60) + "s";
}
Thank you for your help.

you don't flush your buffer, so you see only the last line, cout could be flushed manually using std::cout.flush(); also you should keep in mind that your code rewrites only the begining of the line, so 10s will be changed to 9ss.
this will help
std::cout << '\r' << time;
std::cout.flush();

Related

Displaying seconds, minutes and hours from total seconds in C++ [duplicate]

This question already has answers here:
Converting seconds to hours and minutes and seconds
(11 answers)
Closed 9 months ago.
I am trying to solve a problem where I have a total seconds variable, from which I am trying to determine the hours, minutes and seconds.
I do not want to use any external libraries for this task.
What I have noticed is that my seconds variable seems to result in 1 less than the actual value when it is in int form,
but when it is in double form the answer is correct. Why is this?
I would welcome a different approach, perhaps using the remainder operator.
// Example program
#include <iostream>
#include <string>
int main()
{
int total_seconds;
total_seconds = 3870;
int hours, minutes, seconds;
double total_h, total_m, total_s;
int total_hours_int, total_minutes_int;
total_h = (double)total_seconds / 3600;
total_hours_int = total_seconds / 3600;
hours = total_hours_int;
total_m = (total_h - total_hours_int) * 60;
total_minutes_int = (total_h - total_hours_int) * 60;
minutes = total_minutes_int;
total_s = ((double)total_m - total_minutes_int) * 60;
seconds = ((double)total_m - total_minutes_int) * 60;
//seconds = (double)total_s;
std:: cout << hours;
std:: cout << minutes;
std:: cout << total_s;
std:: cout << seconds;
}
Output : 143029
Update:
The answer below was given before the C++98 tag was added to the question.
The chono library is available since C++11, so you can use it only from that version onwards.
You haven't given any context for this task.
My asnwer below assumes you need to solve the problem in any valid C++ manner (i.e. that it is not mandatory the caculate the numbers "by hand").
If this is the case, you can use the C++ chrono library for that, as shown below. This solution is shorter and less error-prone, and avoids the type issues you had altogether.
The main class I used is std::chrono::duration and it's helper types (as you can see in the link), as well as std::chrono::duration_cast.
#include <iostream>
#include <chrono>
int main()
{
int total_seconds = 3870;
std::chrono::seconds total_secs(total_seconds);
auto hours = std::chrono::duration_cast<std::chrono::hours>(total_secs);
auto mins = std::chrono::duration_cast<std::chrono::minutes>(total_secs - hours);
auto secs = std::chrono::duration_cast<std::chrono::seconds>(total_secs - hours - mins);
std::cout << "totals seconds: " << total_secs.count() << std::endl;
std::cout << " hours: " << hours.count() << std::endl;
std::cout << " minutes: " << mins.count() << std::endl;
std::cout << " seconds: " << secs.count() << std::endl;
}
Output:
totals seconds: 3870
hours: 1
minutes: 4
seconds: 30
I've reopened answear since it was updated to C++98.
Before C++11 it can be done nicely using standard library:
#include <iostream>
#include <string>
#include <ctime>
int main()
{
int seconds;
while (std::cin >> seconds) {
std::tm t = {};
t.tm_sec = seconds;
t.tm_mday = 1;
mktime(&t);
t.tm_hour += t.tm_yday * 24;
char buf[32];
strftime(buf, sizeof(buf), "%H:%M:%S", &t);
std::cout << t.tm_yday << ' ' << seconds << " = " << buf << '\n';
}
return 0;
}
https://godbolt.org/z/ceWWfoP6P

C++ performance degradation (or code must be improved ?)

I am developping a simple program that copies the same string into another one in a loop. I use Visual Studio C++ 2019 Community Edition, and the project type is "Command line".
If I run it for 3,42 seconds then the calculated number of copies per second is 130 601 397, but if I run it for 77,97 seconds then the number of copies per second is 47 469 296...
The more time the program is running, the more performance degradation there is...
Here is the code :
#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <chrono>
#include <string>
using namespace std;
unsigned long repeats_counter = 0;
std::chrono::steady_clock::time_point t1;
std::chrono::steady_clock::time_point t2;
// When CTRL+C (SIGINT), this is executed
signal_callback_handler(int signum) {
t2 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = t2 - t1;
std::cout << "Total execution time " << diff.count() << " s\n";
unsigned long average_repeats_per_sec = (unsigned long)(repeats_counter / diff.count());
std::cout << "Number of average repeats per second was " <<
std::to_string(average_repeats_per_sec) << "\n";
std::cout << "Number of average repeats per minute was " <<
std::to_string(average_repeats_per_sec * 60) << "\n";
cout << "Number of effective repeats = " << repeats_counter << endl;
// Terminate program
exit(signum);
}
int main()
{
signal(SIGINT, signal_callback_handler);
signal(SIGTERM, signal_callback_handler);
std::string from_str, to_str;
cout << "Start copying. CTRL+C to stop." << endl;
t1 = std::chrono::high_resolution_clock::now();
from_str = "the string to be copied";
while (true) {
to_str = from_str;
repeats_counter++;
}
return 0;
}
This could be caused by integer overflow. unsigned long is at least 32 bit and on on some platforms it is equal to unsigned int. unsigned long long partially alleviates the issue, but technically the loop should have some kind of defense against that, albeit it adds to the cost of loop.
There are two problems with code portability, omitted by compiler due to implementation:
std::chrono::steady_clock::time_point should be std::chrono::high_resolution_clock::time_point
signal_callback_handler should have return type void

Measuring time for my array of random numbers to print is always showing 0 seconds

my first post here. Just wondering why my stopwatch is always showing 0 seconds or 0 milliseconds no matter the amount of random numbers in my array. I appreciate the help so much.
Here's my code:
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
double clock_start()
{
clock_t start = clock();
return start;
}
void random_number()
{
int array[10000];
srand(6);
cout << "10k Random numbers: ";
for (int i = 0; i < 10000; i++)
{
array[i] = rand() % 99 + 1;
cout << array[i] << "\n";
}
}
int main()
{
setlocale(LC_ALL, "");
//-------------------------//
random_number();
clock_t elapsed = (clock() - clock_start()) / (CLOCKS_PER_SEC / 1000);
cout << "Stopwatch: " << elapsed << "ms" << " or " << elapsed * 1000 << "s" << endl;
//-------------------------//
system("pause > nul");
return 0;
}
(clock() - clock_start()) will be evaluated in the blink of an eye.
All clock_start() does is return clock(). (In fact, a good optimising compiler will replace clock_start() with clock() !)
The difference will almost certainly be zero. Did you want something like
clock_t start = clock();
random_number();
clock_t elapsed = (clock() - start) / (CLOCKS_PER_SEC / 1000);
instead?
Thanks for the help guys! I'm amazed how fast this community is at replying.
So i deleted the clock_start() function. And i added the:
clock_t start = clock();
to my main function.

Calculating the difference of two times in C++

one of the problems I'm working on requires an input of two time values (being in hours, minutes and seconds)in a 24h00 format. I have already declared my variables, input and output statements with regards to my main program. I'm just having trouble with my void statement CalcDiff to calculate the difference of the two time inputs. All values have been declared of type int. Should inputs(eg. sec and sec2) be compared first to see which is greater before calculating the difference? I'm assuming the order of variables would be important too(calculating the difference of the hours before the minutes, before the seconds)? I'm new to C++ so my apologies if I'm missing anything obvious.
// Computes time difference of two time periods in 24h00 format
// Time periods are input
#include <iostream>
using namespace std;
int seconds,seconds2, minutes, minutes2, hours, hours2;
void CalcDiff(int seconds, int seconds2 int minutes, int minutes2, int
hours, int hours2);
int main()
{
int sec, sec2, min, min2, hr, hr2, diff;
cout << "Enter the first time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> hr >> min >> sec;
cout << "Enter the second time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> hr2 >> min2 >> sec2;
CalcDiff(int sec, int sec2, int min, int min2, int hr, int hr2,
diff);
cout << endl << "Difference in times: " << hr << ":" << min << ":"
<< sec;
cout << " - " << hr2 << ":" << min2 << ":" << sec2;
return 0;
}
void CalcDiff(int seconds, int seconds2, int minutes, int minutes2, int
hour, int hour2, diff)
Use <chrono> plus an existing library.
#include "date.h"
#include <iostream>
int
main()
{
std::chrono::seconds t1, t2;
std::cout << "Enter the first time [h]h:mm:ss: ";
std::cin >> date::parse("%T", t1);
if (std::cin.fail())
return 1;
std::cout << "Enter the second time [h]h:mm:ss: ";
std::cin >> date::parse(" %T", t2);
if (std::cin.fail())
return 1;
std::cout << date::format("Difference in times: %T\n", t1 - t2);
}
The above library is free, open-source, and being proposed for standardization.
I had the same problem and my solution was this code, my perspective is to get both times in seconds and then subtract them to know the difference. time calculations are made inside the IF statement. the rest of the code is to print the results, I added many variables to try to make it more explicit and understandable.
#include <iostream>
using namespace std;
int main()
{
int h1,h2,m1,m2,s1,s2;
long TotalSeconds = 0;
cout << "Enter the first time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> h1 >> m1 >> s1;
cout << "Enter the second time." << endl;
cout << "Enter hours, minutes and seconds: ";
cin >> h2 >> m2 >> s2;
// Difference Between Times IN Seconds
// this code must be in your function
if( h1 > h2 ){
TotalSeconds += 86400 - ((h1*3600)+(m1*60)+(s1));
TotalSeconds += ((h2*3600)+(m2*60)+(s2));
}else{
// Time 2 - Time 1
TotalSeconds = ((h2*3600)+(m2*60)+(s2)) - ((h1*3600)+(m1*60)+(s1));
}
cout << "Total Seconds: " << TotalSeconds << endl;
cout << "Time Difference :\t";
long hours, minutes, seconds;
hours = TotalSeconds / 3600;
cout << hours << ":";
TotalSeconds -= hours*3600;
minutes = TotalSeconds / 60;
cout << minutes << ":";
TotalSeconds -= minutes*60;
seconds = TotalSeconds;
cout << seconds << endl;
return 0;
}
Another Example using C' Style, in this example you must input time string like this 01:23:11
#include <stdio.h>
#include <stdlib.h>
int main()
{
int h1,h2,m1,m2,s1,s2;
long segundos = 0;
// Hora Inicial
scanf("%i : %i : %i",&h1,&m1,&s1);
// Hora Final
scanf("%i : %i : %i",&h2,&m2,&s2);
// HORAS
if( h1 > h2 ){
segundos += 86400 - ((h1*3600)+(m1*60)+(s1));
segundos += ((h2*3600)+(m2*60)+(s2));
}else{
// Tiempo 2 - Tiempo 1
segundos = ((h2*3600)+(m2*60)+(s2)) - ((h1*3600)+(m1*60)+(s1));
}
printf("%ld",segundos);
return 0;
}
Aside from there already existing classes to handle this, here is a solution idea with explanation.
First of all, sec, sec2, min, min2... this is a list of different variables. If you have such a long list, this is a sign that something is amiss. This is C++, so use OOP. That is, use classes.
One header for such a class could be
class Time {
private:
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
public:
Time(const unsigned char _seconds, const unsigned char _minutes,
const unsigned char __hours);
Time(const unsigned int _seconds);
Time difference(const Time& other) const;
unsigned int to_total_seconds() const;
}
This is a far cleaner approach - you don't need all the code right where you use it. Implementations:
Time Time::difference(const Time& other) const {
int difference_seconds = (int) this.to_total_seconds() - (int) other.to_total_seconds();
return Time((unsigned int) std::abs(difference_seconds));
}
unsigned int Time::to_total_seconds() const{
return seconds + 60.*minutes + 60*60*hours;
}
Time::Time(const unsigned int _seconds){
seconds = _seconds % (60*60);
minutes = (_seconds / 60) % 60;
hours = _seconds / (60*60);
}
Time::Time(const unsigned char _seconds, const unsigned char _minutes,
const unsigned char __hours) :
seconds(_seconds), minutes(_minutes), hours(_hours) {
assert(seconds < 60);
assert(minutes < 60);
}
Another approach would be to directly store the total seconds.
I mean, you could do things like doing actual subtractions, like doing difference 6:12 to 4:50 by subtracting 50 from 12 in minutes, resulting in 38 with a remainder, then 6 minus (4 + remainder) = 1 -> 1:38 difference. But why do that when you can simply subtract the seconds and take their absolute value?
But more importantly, keep your main clean. Large procedural code is a clear sign that a class is missing.
(Of course you'll have to add something to the code that gets the values out, preferably a printer. Since there are possibilities for inconsistence, public members are not recommended here.)
Try using std::chrono
void calcDiff(int h1, int m1, int s1, int h2, int m2, int s2){
std::chrono::seconds d = std::chrono::hours(h2-h1)
+ std::chrono::minutes(m2-m1)
+ std::chrono::seconds(s2-s1);
std::cout << std::chrono::duration_cast<std::chrono::hours>(d).count() << "h" <<
std::chrono::duration_cast<std::chrono::minutes>(d % std::chrono::hours(1)).count() << "m" <<
std::chrono::duration_cast<std::chrono::seconds>(d % std::chrono::minutes(1)).count() << "s" << std::endl;
}
int main(){
calcDiff(13, 30, 45, 18, 40, 20); // 5h9m35s
calcDiff(20, 30, 45, 18, 40, 20); // -1h-50m-25s
return 0;
}
The negative result might be a little wierd, but i am sure you can make it work whatever way you want.
I decided to go with converting the minutes and hours to seconds and work the difference for the time periods through a void function I called CalcDiff. I used three referenced variables, FinSec, FinMin and FinHr to store the differences after converting the new DiffSec to the new values.
My program for the void statement is:
void CalcDiff(int seconds, int seconds2, int minutes, int minutes2, int
hour, int hour2, int& FinSec, int& FinMin, int& FinHr)
{
int TotalSec1, TotalSec2, DiffSec, tempMin;
TotalSec1= (hour*3600)+(minutes*60)+seconds;
TotalSec2= (hour2*3600)+(minutes2*60)+seconds2;
if(TotalSec1>TotalSec2)
DiffSec = TotalSec1 - TotalSec2;
else
DiffSec = TotalSec2 - TotalSec1;
FinSec = DiffSec%60;
tempMin = DiffSec/60;
FinMin = tempMin%60;
FinHr = FinMin/60;
}
first of all the syntax of function call should be
CalcDiff( sec, sec2, min, min2, hr, hr2);
instead of
CalcDiff(int sec, int sec2, int min, int min2, int hr, int hr2,
diff);
in the main section
function definition the code should be
void CalcDiff(int seconds, int seconds2, int minutes, int minutes2, int
hour, int hour2, diff)
{
\\ write the code for subtraction here
}

How to append system time to a string variable

#include<iostream>
#include<ctime>
#include<string>
using namespace std;
int main()
{
string NowTime;
time_t now;
struct tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
NowTime = nowLocal.tm_hour + ':' + nowLocal.tm_min + ':' + nowLocal.tm_sec;
cout<< NowTime;
}
When I run the program, it display nothing, can someone help me? I am totally new in programming.
If you try
cout << nowLocal.tm_hour + ':' + nowLocal.tm_min + ':' + nowLocal.tm_sec;
you'll see an integer, not anything resembling a time.
This is because it's the sum of five integers - the characters are promoted to integers, and then it's all added up.
The simplest fix is to not build a string at all but to output the parts individually:
cout << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
Otherwise, you need to convert those numbers to strings:
NowTime = std::to_string(nowLocal.tm_hour) + ':' + std::to_string(nowLocal.tm_min) + ':' + std::to_string(nowLocal.tm_sec);
or, you can use a std::ostringstream, which works just like std::cout and other streams, but writes to a std::string:
std::ostringstream ss;
ss << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
NowTime = ss.str();
The line:
NowTime = nowLocal.tm_hour + ':' + nowLocal.tm_min + ':' + nowLocal.tm_sec;
is adding the hour, minute, and second to the numeric value of the colon symbol, since char is implicitly coerced to an int. That value is then being interpreted as a char in the string assignment operator.
Instead, you can simply output the values directly to cout. They will be formatted appropriately by cout's stream insertion operator <<.
#include<iostream>
#include<ctime>
#include<string>
using namespace std;
int main()
{
string NowTime;
time_t now;
tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
cout << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
return 0;
}
If you would instead want to store them in a string, read up about stringstreams. They have a similar syntax to cout and can make formatting strings much easier.
Instead of having to put the result in a variable, you could output it like this:
cout << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
Live Example
Also, if you want to keep the variable, do this:
NowTime = std::to_string(nowLocal.tm_hour) + ':' + std::to_string(nowLocal.tm_min) + ':' + std::to_string(nowLocal.tm_sec);
cout << NowTime;
Try this:
#include<iostream>
#include<ctime>
#include<string>
#include <sstream>
using namespace std;
int main()
{
string NowTime;
time_t now;
struct tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
stringstream s;
s<<nowLocal.tm_hour;
s<<":";
s<<nowLocal.tm_min;
s<<":";
s<<nowLocal.tm_sec;
NowTime = s.str();
cout<< NowTime;
}
You cannot cas directly from int to string and you need put values into stream and then to string.
What about using iostringstream to build the string you want?
#include<iostream>
#include<ctime>
#include<string>
#include <sstream>
using namespace std;
int main()
{
ostringstream NowTime;
time_t now;
struct tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
NowTime << nowLocal.tm_hour << ":" << nowLocal.tm_min << ":" << nowLocal.tm_sec;
cout<< NowTime.str() << endl;
}
Or for the purposes of your program you could simple use std::cout which also happens to be an output stream.
cout << nowLocal.tm_hour << ":" << nowLocal.tm_min << ":" << nowLocal.tm_sec << endl;
Since it looks like you're pre-c++11 and can't use std::to_string. Here's a C-like way of doing it, sticking to the includes you're currently using.
#include<iostream>
#include<ctime>
#include<string>
using namespace std;
#define STR_LEN 128
int main()
{
string nowTime;
time_t now;
struct tm nowLocal;
now = time( NULL ); // get the time from the OS
nowLocal = *localtime( &now );
char hour[ STR_LEN ], min[ STR_LEN ], sec[ STR_LEN ];
sprintf( hour, "%d", nowLocal.tm_hour );
sprintf( min, "%d", nowLocal.tm_min );
sprintf( sec, "%d", nowLocal.tm_sec );
nowTime = string( hour ) + ':' + string( min ) + ':' + string( sec );
cout << nowTime << endl;
}
How append system time to a string?
My answer is to build a convenience function.
If you really only need hour, minute, second, then you need not use the relatively slow localtime(). (on the other hand, if you do need more, I think you should prefer localtime_r() for the conversion).
For an embedded system several contracts back, I found this conversion to be a relatively slow function and chose to avoid it. The algorithms to handle leap days, centuries, etc. appear simple enough. I suspect I considered it slow simply because it calculates more than I needed in that application that was trying to do the conversion many times per second.
There exists a simpler (and probably still faster) approach involving modular arithmetic. It starts the same - with a time(0) (and thus I suspect what I am doing here is 'hidden' in the localtime_r() function). Side note 1 - on my older Dell running Ubuntu 15.10, time(0) is simply the fastest access to the wall clock, measuring about 6 or 7 ns 'typical' duration. Side note 2 - time_t may change someday. "The time_t Wikipedia article article sheds some light on this. The bottom line is that the type of time_t is not guaranteed in the C specification."
The code I currently use to conveniently generate a time stamp string:
std::string hhCmmCssGet(time_t tt = 0) // tt has default value
{
time_t now = ( tt ? tt : time(0) );
static time_t prev = 0;
static char hhmmss[] = "hh:mm:ss";
if (prev != now)
{
prev = now;
const int32_t CST = -6;
int64_t hr = ((now / 3600) % 24) + CST; // hr of day, CST offset
if (hr < 0) hr += 24;
uint64_t min = ((now / 60) % 60); // min of day
uint64_t sec = (now % 60); // sec of day
std::stringstream ss;
ss << std::dec
<< std::setfill('0') << std::setw(2) << hr << ":"
<< std::setfill('0') << std::setw(2) << min << ":"
<< std::setfill('0') << std::setw(2) << sec;
for (size_t i=0; i<8; i++) // transfer new value
hhmmss[i] = ss.str()[i]; // into static hhmmss
}
std::string retVal(hhmmss);
return(retVal);
}
The static items and "if (prev != now)" clause, allow this function to be invoked thousands of times per second ... with much reduced effort. The second, after all, only updates 1ce per second. And note that the std::stringstream stuff and modular arithmetic operations only run 1ce per second.