C++: How to get vector to print user input? - c++

I'm having some trouble figuring out how to print out my vector's user input. I think there's something wrong specifically with my iterator loop, but I'm not sure what. I've been toying around with this and I'm stumped. I'm also having trouble with my sentinel value - my program ceases to continue after entering in my sentinel value. Am I missing something?
Any help you could provide would be greatly appreciated.
Here's my code: (there are some variables here that you might notice that aren't being used in this sample of code. i'm using those variables for another portion of my program).
Any help that you could provide in regards to this would be INCREDIBLY helpful. Thank you.

You're declaring your check_amounts vector a second time, right before your output loop, so you're outputting the contents of an empty vector. Delete the second declaration.

Your code got caught in infinite loop at :
for (i = 0; amount < length; i++) length /= 10;
Because amount = -1, length = 0.
Also do not use != for double values, e.g. (amount != -1). Use < or > . Equality check is not reliable due to inexact bit-pattern

this is what i get when i run your code:
This program inputs a dollar amount and prints it in check-format.
Input up to five check amounts, one at a time. (Enter -1 to quit)
5
Input up to five check amounts, one at a time. (Enter -1 to quit)
10
Input up to five check amounts, one at a time. (Enter -1 to quit)
15
Input up to five check amounts, one at a time. (Enter -1 to quit)
20
Input up to five check amounts, one at a time. (Enter -1 to quit)
25
The check-formated dollar amount for your check(s) are printed as follows: 5 **** 25.00
10 **** 25.00
15 **** 25.00
20 **** 25.00
25 **** 25.00
Can't see a problem with printing out vector's user input. Avik Paul is right for the sentinel case by the way. You should be using the last valid amount maybe.

Related

C++ - condition in -for loop- isn't evaluated as I think it should be

I'm quite new to C++ and I have some kind of problem. I would like to ask if someone could explain to me why the evaluation within the for condition does not work.
This is a part of a program I've written, there is a rpm value which is given by the user and gets assorted to a rpm_case to do some calculations later.
What it SHOULD do:
rpm between 800 up to 1200 ==> rpm_case = 0
rpm between 1200 up to 1800 ==> rpm_case = 1
rpm between 1800 up to 2500 ==> rpm_case = 2
rpm between 2500 to 3500 ==> rpm_case = 3
========================================================================
in the first place I had some 30-line long if-construction for that but I discarded that already and replaced it with the following much shorted and nicer way to write it (this works as expected):
const float rpm_bases[known_rpm_bases] = {800, 1200, 1800, 2500, 3500};
short rpm_case;
for (rpm_case=0;; rpm_case++) {
if (!(rpm > rpm_bases[rpm_case+1])) {break;}
}
but I'm still not happy because I was really trying to get rid of the if with the for loop.
But the for- loop instead always loops over the entire size of the array instead breaking at the considered point.
const float rpm_bases[known_rpm_bases] = {800, 1200, 1800, 2500, 3500};
short rpm_case;
for (rpm_case=0; (!(rpm > rpm_bases[rpm_case+1])); rpm_case++) {}
?? It somehow seems as it is not possible to evaluate a array with the counter-variable within the conditional part of an for-loop??? Or am I just doing something totally wrong I don't want to exclude that option either.
Big Thanks to everyone in advance.
The middle expression of a for statement is the condition that must be true for the loop to repeat. Therefore, it must be the opposite of the condition that must be true for the loop to break.
For this reason, you must negate the expression by removing the ! (NOT) operator, like this:
for (rpm_case=0; rpm > rpm_bases[rpm_case+1]; rpm_case++);
This expression will work for the cases stated in your question. However, if rpm is higher than 3500, it will cause the array rpm_bases to be accessed out of bounds, causing undefined behavior. Therefore, it would be safer to write the loop in the following way:
for ( rpm_case=0; rpm_case < known_rpm_bases; rpm_case++ )
{
if ( rpm <= rpm_bases[rpm_case] ) break;
}
That way, your program will just give you an additional increment of rpm_case if rpm is higher than the highest value, instead of accessing the array out of bounds causing undefinied behavior.
This is effectively just a typo.
The loop condition is for how long the loop does keep running, not to describe when it ends.
Invert it.

RRD Time since last non-change of counter

I have a RRD DCOUNTER, which gets its data from the water meter: so many units since start of the program which looks at the meter.
So the input might be 2,3,4,5,5,5,5,8,12,13,13,14,14,14,14,14
That means the flow is 1,1,1,0,0,0,0,3,4,1,0,1,0,0,0,0,0
I want a graph showing minutes since last rest
0,1,2,0,1,2,3,0,0,0,0,0,0,1,2,3,4,5
If the flow is never zero, there must be a leak.
Hopefully the graph should rise steadily from bedtime to wakeup, and from leaving to work to coming back.
Ideas?
First, you set up your input data source as a COUNTER type, so that you will be storing the changes, IE the flow.
Now, you can define a calculated datasource (for graphs etc) that counts the minutes since the last zero, using something like:
IF ( flow == 0 )
THEN
timesincerest = 0
ELSE
timesincerest = previous value of timesincerest + 1
END
In RPN, that would be:
timesincerest = flow, 0, GT, PREV(timesincerest), STEPWIDTH, +, 0, IF
This will give you a count of the number of seconds since the last reset.

C++ Program, Console/Terminal Output. How to implement "updating text"

I am writing a C++ program, which runs a long data analysis algorithm. It takes several days to finish running, so it is useful to have a prompt which outputs the "percentage complete" every time a new loop in the program starts so that the user (me) knows the computer isn't sitting in an infinite loop somewhere or has crashed.
At the moment I am doing this the most basic way, by computing the percentage complete as a floating point number and doing:
std::cout << "Percentage complete: " << percentage_complete << " %" << std::endl;
But, when the program has a million loops to run, this is kind of messy. In addition, if the terminal scrollback is only 1000 lines, then I lose the initial debug info printed out at the start once the program is 0.1 % complete.
I would like to copy an idea I have seen in other programs, where instead of writing a new line each time with the percentage complete, I simply replace the last line written to the terminal with the new percentage complete.
How can I do this? Is that possible? And if so, can this be done in a cross platform way? Are there several methods of doing this?
I am unsure how to describe what I am trying to do perfectly clearly, so I hope that this clear enough that you understand what I am trying to do.
To clarify, rather than seeing this:
Running program.
Debug info:
Total number of loops: 1000000
Percentage complete: 0 %
Percentage complete: 0.001 %
Percentage complete: 0.002 %
.
.
.
Percentage complete: 1.835 %
I would like to see this:
Running program.
Debug info:
Total number of loops: 1000000
Percentage complete: 1.835 %
And then on the next loop the terminal should update to this:
Running program.
Debug info:
Total number of loops: 1000000
Percentage complete: 1.836 %
I hope that's enough information.
(Okay, so this output would actually be for 100000 steps, not 1000000.)
Instead of \n or std::endl, use \r. The difference is that the latter returns the cursor to the beginning if the line without a new line.
Disclaimer (as per Lightness' objections): This is not necessarily portable, so YMMV.

Timed button press

I was playing a racing game and after a while I started thinking how the gear shifting mechanism was implemented. I'm trying to do something similar, but much more simple. In this program I am printing out the number 128. as time goes on the number decreases. If I press a key at 4 secs the number should revert back to 128 and start decreasing again. My main issue is finding a way to calculate the multiplier as you see below. As you can see What I'm currently doing does not work. After 800 miliseconds the resulting value increases again and goes past 1. I want the max value at 1 so that when i press a button at 4 seconds the multiplier is 1 to get exactly 128. Thanks for your help in advance.
start timer
loop after this point
get time to variable
if button press
multiplier=1-(abs(time-400)/400)
clear timer
get time to variable
print (128*multiplier)*(100/(time+100))
Thanks for the help in advance.
start timer
loop after this point
get time to variable
if button press
multiplier=1-(abs(time-400)/400)
if multiplier < 0
multiplier = 0
clear timer
get time to variable
print (128*multiplier)*(100/(time+100))

C++ Program performs better when piped

I haven't done any programming in a decade. I wanted to get back into it, so I made this little pointless program as practice.
The easiest way to describe what it does is with output of my --help codeblock:
./prng_bench --help
./prng_bench: usage: ./prng_bench $N $B [$T]
This program will generate an N digit base(B) random number until
all N digits are the same.
Once a repeating N digit base(B) number is found, the following statistics are displayed:
-Decimal value of all N digits.
-Time & number of tries taken to randomly find.
Optionally, this process is repeated T times.
When running multiple repititions, averages for all N digit base(B)
numbers are displayed at the end, as well as total time and total tries.
My "problem" is that when the problem is "easy", say a 3 digit base 10 number, and I have it do a large number of passes the "total time" is less when piped to grep. ie:
command ; command |grep took :
./prng_bench 3 10 999999 ; ./prng_bench 3 10 999999|grep took
....
Pass# 999999: All 3 base(10) digits = 3 base(10). Time: 0.00005 secs. Tries: 23
It took 191.86701 secs & 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
An average of 0.00019 secs & 99 tries was needed to find each one.
It took 159.32355 secs & 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
If I run the same command many times w/o grep time is always VERY close.
I'm using srand(1234) for now, to test. The code between my calls to clock_gettime() for start and stop do not involve any stream manipulation, which would obviously affect time. I realize this is an exercise in futility, but I'd like to know why it behaves this way.
Below is heart of the program. Here's a link to the full source on DB if anybody wants to compile and test. https://www.dropbox.com/s/bczggar2pqzp9g1/prng_bench.cpp
clock_gettime() requires -lrt.
for (int pass_num=1; pass_num<=passes; pass_num++) { //Executes $passes # of times.
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &temp_time); //get time
start_time = timetodouble(temp_time); //convert time to double, store as start_time
for(i=1, tries=0; i!=0; tries++) { //loops until 'comparison for' fully completes. counts reps as 'tries'. <------------
for (i=0; i<Ndigits; i++) //Move forward through array. |
results[i]=(rand()%base); //assign random num of base to element (digit). |
/*for (i=0; i<Ndigits; i++) //---Debug Lines--------------- |
std::cout<<" "<<results[i]; //---a LOT of output.---------- |
std::cout << "\n"; //---Comment/decoment to disable/enable.*/ // |
for (i=Ndigits-1; i>0 && results[i]==results[0]; i--); //Move through array, != element breaks & i!=0, new digits drawn. -|
} //If all are equal i will be 0, nested for condition satisfied. -|
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &temp_time); //get time
draw_time = (timetodouble(temp_time) - start_time); //convert time to dbl, subtract start_time, set draw_time to diff.
total_time += draw_time; //add time for this pass to total.
total_tries += tries; //add tries for this pass to total.
/*Formated output for each pass:
Pass# ---: All -- base(--) digits = -- base(10) Time: ----.---- secs. Tries: ----- (LINE) */
std::cout<<"Pass# "<<std::setw(width_pass)<<pass_num<<": All "<<Ndigits<<" base("<<base<<") digits = "
<<std::setw(width_base)<<results[0]<<" base(10). Time: "<<std::setw(width_time)<<draw_time
<<" secs. Tries: "<<tries<<"\n";
}
if(passes==1) return 0; //No need for totals and averages of 1 pass.
/* It took ----.---- secs & ------ tries to find --- repeating -- digit base(--) numbers. (LINE)
An average of ---.---- secs & ---- tries was needed to find each one. (LINE)(LINE) */
std::cout<<"It took "<<total_time<<" secs & "<<total_tries<<" tries to find "
<<passes<<" repeating "<<Ndigits<<" digit base("<<base<<") numbers.\n"
<<"An average of "<<total_time/passes<<" secs & "<<total_tries/passes
<<" tries was needed to find each one. \n\n";
return 0;
Printing to the screen is very slow in comparison to a pipe or running without printing. Piping to grep keeps you from doing it.
It is not about printing to the screen; it is about the output being a terminal (tty).
According to the POSIX spec:
When opened, the standard error stream is not fully buffered; the
standard input and standard output streams are fully buffered if and
only if the stream can be determined not to refer to an interactive
device.
Linux interprets this to make the FILE * (i.e. stdio) stdout line-buffered when the output is a tty (e.g. your terminal window), and block-buffered otherwise (e.g. your pipe).
The reason sync_with_stdio makes a difference is that when it is enabled, the C++ cout stream inherits this behavior. When you set it to false, it is no longer bound by that behavior and thus becomes block buffered.
Block buffering is faster because it avoids the overhead of flushing the buffer on every newline.
You can further verify this by piping to cat instead of grep. The difference is the pipe itself, not the screen per se.
Thank you Collin & Nemo. I was certain that because I wasn't calling std::cout between getting start & stop times that it wouldn't have an effect. Not so. I think this is due to optimizations that the compiler performs even with -O0 or 'defaults'.
What I think is happening...? I think that as Collin suggested, the compiler is trying to be clever about when it writes to the TTY. And, as Nemo pointed out, cout inherits the line buffered properties of stdio.
I'm able to reduce the effect, but not eliminate, by using:
std::cout.sync_with_stdio(false);
From my limited reading on this, it should be called before any output operations are done.
Here's source for no_sync version: https://www.dropbox.com/s/wugo7hxvu9ao8i3/prng_bench_no_sync.cpp
./no_sync 3 10 999999;./no_sync 3 10 999999|grep took
Compiled with -O0
999999: All 3 base(10) digits = 3 base(10) Time: 0.00004 secs. Tries: 23
It took 166.30801 secs & 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
An average of 0.00017 secs & 99 tries was needed to find each one.
It took 163.72914 secs & 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
Complied with -O3
999999: All 3 base(10) digits = 3 base(10) Time: 0.00003 secs. Tries: 23
It took 143.23234 secs & 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
An average of 0.00014 secs & 99 tries was needed to find each one.
It took 140.36195 secs & 99947208 tries to find 999999 repeating 3 digit base(10) numbers.
Specifying not to sync with stdio changed my delta between piped and non-piped from over 30 seconds to less than 3. See original question for original delta it was ~191 - ~160
To further test I created another version using a struct to store stats about each pass. This method does all output after all passes are complete. I want to emphasize that this is probably a terrible idea. I'm allowing a command line argument to determine the size of a dynamically allocated array of structs containing an int, double and unsigned long. I can't even run this version with 999,999 passes. I get a segmentation fault. https://www.dropbox.com/s/785ntsm622q9mwd/prng_bench_struct.cpp
./struct_prng 3 10 99999;./struct_prng 3 10 99999|grep took
Pass# 99999: All 3 base(10) digits = 6 base(10) Time: 0.00025 secs. Tries: 193
It took 13.10071 secs & 9970298 tries to find 99999 repeating 3 digit base(10) numbers.
An average of 0.00013 secs & 99 tries was needed to find each one.
It took 13.12466 secs & 9970298 tries to find 99999 repeating 3 digit base(10) numbers.
What I've learned from this is that you can't count on the order you've coded things being the order they're executed in. In future programs I'll probably implement getopt instead of writing my own parse_args function. This would allow me to surpress extraneous output on high repetition loops, by requiring users to use the -v switch if they want to see it.
I hope the further testing proves useful to anybody wondering about piping and output in loops. All of the results I've posted were obtained on a RasPi. All of the source codes linked are GPL, just because that's the first license I could think of... I really have no self-aggrandizing need for the copyleft provisions of the GPL, I just wanted to be clear that it's free, but without warranty or liability.
Note that all of the sources linked have the call to srand(...) commented out, so all of your pseudo-random results will be exactly the same.