A program is divided into N functions.
Like the following code snippets: after calling each function, I wanna show the progress count/N
how to count N at compile time ?
#include <iostream>
using namespace std;
double progress()
{
int const total = 4; // how to get 4?
static int counter = 0;
return static_cast<double>(counter++) / static_cast<double>(total);
}
int main()
{
cout << progress() << endl; // 0.25
cout << progress() << endl; // 0.5
cout << progress() << endl; // 0.75
cout << progress() << endl; // 1.0
return 0;
}
I tried constexpr function, but cannot increment a variable.
Imagine the following code:
int main() {
cout << "N = ";
int N;
cin >> N;
for (int i = 0; i < N; ++i) cout << 'progress()' << endl;
}
There is absolutely no way, the compiler can know how many times the function will be executed. So you need to determine the number using the logic of your data.
If you want to know how many times you call progress without loops, recursions, conditions etc., the only way I can think of is using external tool on the source file. E.g.
cat source.cpp | grep -o progress() | wc -l
Just remember to subtract 1 from the result, which accounts for the function definition.
You can't do it, but you could fake it by making the printing happen after N (function call count) is known.
static struct counter_impl {
int n = 0;
constexpr void operator ()() noexcept { ++n; }
friend std::ostream& operator<<(std::ostream& os, counter_impl const& self) {
os << std::fixed;
std::generate_n(std::ostream_iterator<double>(os, "\n"), self.n,
[i = 1, N = static_cast<double>(self.n)] () mutable { return i++ / N; });
return os << std::defaultfloat;
}
} counter;
int main() {
counter();
std::cout << counter; // 1.00
}
Live example on compiler explorer
Unfortunately, you cannot.
This is not something that can be determined at compile time.
See https://en.wikipedia.org/wiki/Halting_problem
I am extremely confused. I have to follow these specific guidelines:
Make a program that will compute and output the average of 10 exam scores, entered by the user. Finish the function, so that the main will work correctly. Feel free to modify the main as you please as well.
I do not believe we need to change the main and do not believe we should use 10 variables. Here is the code I must add to, I believe the main is finished. Your help is very appreciated!!!!
#include <iostream>
using namespace std;
NOT ADD CODE HERE!!!
float calculateAverageTestScore(int amountOfScores);
int main(void)
{
const int NUMBER_OF_SCORES = 10;
cout << "The average test score was: " << calculateAverageTestScore(NUMBER_OF_SCORES) << endl;
return 0;
}
//INPUT: an amount of test scores
//OUTPUT: the average of these scores
//This function will obtain amountOfScores test scores from the user, and return
//their average - to be used elsewhere.
float calculateAverageTestScore(int amountOfScores)
{
float average;
//add code here
return average;
}
Should do the trick.
#include <iostream>
#include <string>
float calculateAverageTestScore(int amountOfScores);
int main() {
const int NUMBER_OF_SCORES = 10;
const float score = calculateAverageTestScore(NUMBER_OF_SCORES);
std::cout << "The average test score was: " << score << '\n';
}
float calculateAverageTestScore(int amountOfScores) {
float sum = 0;
std::string buffer;
for (int i = 0; i < amountOfScores; ++i) {
std::cout << "score #" << i + 1 << ": ";
std::getline(std::cin, buffer);
sum += std::stof(buffer); // TODO: Error handling
}
return sum / amountOfScores;
}
I want to start off by saying I am brand new to C++. I have been learning off of websites and trying for hours shuffling around my code and trying new things in an attempt to solve this.
When I reference a variable while in the function where the variable is modified, it returns the correct value. Once that function is left, even though I've passed the variables on to the next function, the values get reset. I even went about adding couts here and there to display values to help me debug, but nothing was yielding any results. Can someone point me in the right direction please? I'll post my code below. Thanks for the help, guys.
#include <iostream>
//void Loop(int Total, int Spend);
//int NewTotal(int Total, int Spend);
//void Spent(int Total, int Spend);
void UserInput(int Total, int Spend);
// Loops back to UserInput() for next entry input
void Loop(int Total, int Spend)
{
UserInput(Total, Spend);
}
int NewTotal(int Total, int Spend)
{
std::cout << "Output of Total is: " << Total << std::endl;
std::cout << "Output of Spend is: " << Spend << std::endl;
return Total + Spend;
}
void Expense()
{
std::cout << "Please enter a description of your expense!" << std::endl;
char ExpenseDesc;
std::cin >> ExpenseDesc;
std::cout << "You described your expense as: " << std::endl;
std::cout << ExpenseDesc << std::endl;
}
void Spent(int Total, int Spend)
{
std::cout << "Please enter the amount you spent!" << std::endl;
std::cin >> Spend;
NewTotal(Total, Spend);
}
void UserInput(int Total, int Spend)
{
Expense();
Spent(Total, Spend);
std::cout << "Result of Total and Spend (NewTotal) is: " << Total + Spend << std::endl;
std::cout << "Record saved!" << std::endl;
std::cout << "So far, you have spent " << NewTotal(Total, Spend) << "!" << std::endl; //int Total & int Spend not retaining value when NewTotal(Total, Spend) gets called again to return value
std::cout << "Ready for next entry!" << std::endl;
Loop(Total, Spend);
}
int main()
{
int Total;
int Spend;
Spend = 0;
Total = 0;
UserInput(Total, Spend);
return 0;
}
Essentially, this is a very basic prompt that asks you for a description of a transaction (which only accepts one character, I need to fix that) and a transaction amount. Upon finishing that entry, you can make another one and the program is supposed to add the old total to the new total to arrive at a total spendings so far, and then repeat the prompt.
You need to either pass your variables by reference or return them from your functions. As it stands right now, you are creating copies of each variable that are local to each function, modifying the copies, and then discarding them at the end of scope.
Returning values:
std::pair<int, int> Spent(int Total, int Spend) {
...
return std::make_pair(Total, Spend);
}
// Getting values out
std::pair<int, int> result = Spent(Total, Spend);
int newTotal = result.first;
int newSpend = result.second;
// or
int newTotal, newSpend;
std::tie(newTotal, newSpend) = Spent(Total, Spend);
// or (C++17)
auto [newTotal, newSpend] = Spent(Total, Spend);
Reference parameters:
void Spent(int& Total, int& Spend) {
// Modifications to Total and Spend in this function will apply to the originals, not copies
...
}
Another option is to pass pointers:
void f(int* Total, int* Spent)
{
*Total = ...;
*Spent = ...;
}
Or use std::tuple:
std::tuple<int, int> f(int Total, int Spent)
{
...
return std::tuple<int, int>(Total, Spent);
}
I have created a program that prints out all of the permutations of the characters provided through command-line arguments and decided I wanted to compare execution time to an equivalent program written in Java.
The program worked until I decided to find the permutations multiple times in order to get an average execution time.
void avgTime(char**& argv, int times) {
if (sizeof(argv) > 1) {
long permutationAmnt;
clock_t s_start, s_end, t_start, t_end;
float s_runms, t_runms;
long avg_time;
for (int count = 0; count < times; count++) {
t_start = clock();
for (int i = 1; i < sizeof(argv); i++) {
s_start = clock();
permutationAmnt = permutations(std::string(argv[i]));
s_end = clock();
s_runms = ((float)s_end - s_start) / CLOCKS_PER_SEC * 1000;
std::cout << "SUCCESS (" << s_runms << "ms for " << permutationAmnt << " permutations)" << std::endl << std::endl;
}
t_end = clock();
t_runms = ((float) t_end - t_start) / CLOCKS_PER_SEC * 1000;
std::cout << std::endl << "TOTAL RUNTIME: " << t_runms << "ms" << std::endl;
avg_time += t_runms;
}
std::cout << "AVERAGE RUNTIME: " << avg_time / times << "ms" << std::endl;
}
}
int main(int argc, char** argv) {
avgTime(argv, 10);
return 0;
}
The first for-loop in avgTime() only executes a single time (putting a cout inside of it only prints one time) and the program appears to terminate after the nested for-loop breaks.
I am not sure if the problem is with some of the code from avgTime() or if it comes from one of the helper functions, like permute(). Either way here is the code for each of the helper functions as well as the includes (p.s. num is declared outside of any functions).
/*
* Calls the recursive permute() function then
* returns the total amount of permutations possible
* for the given input.
*
* NOTE: the num variable is used in the permute() function
* for numbering the permutations printed as output (see next function
* for clarificiation)
*/
long permutations(const std::string& arg) {
long totalPermutations = factorial(arg.size()); //self-explanatory
num = 1;
permute(arg, 0);
return totalPermutations;
}
/*
* Recursively prints out each permutation
* of the characters in the argument, str
*/
void permute(const std::string& str, int place) {
if (place == str.size() - 1) std::cout << ((num <= 10) ? "0" : "") << num++ << ". " << str << std::endl;
for (int i = place; i < str.size(); i++) {
permute(swap(place, i, str), place + 1); //self-explanatory
}
}
long factorial(int num) {
if (num < 2) {
return 1;
}
return factorial(num - 1) * num;
}
std::string swap(int i, int j, const std::string& str) {
std::string s(str);
s[i] = s[j];
s[j] = str[i];
return s;
}
NOTE: the permute() function appears before the permutation() function in the source code and is visible to all the necessary callers of it.
//Includes and namespace stuff
#include <iostream>
#include <string>
#include <time.h>
I would appreciate any help that you guys can offer, if there is any additional information that you would like me to provide just let me know. Thanks again for any help.
P.S. No, this isn't a homework assignment :P
EDIT: Removed using namespace std; and adjusted the code accordingly to avoid confusion between the function std::swap() and my own swap() function. Also, added the swap() and factorial() functions to avoid any ambiguity. I apologize for the confusion this caused.
I was using sizeof(argv) rather than just using argc. Switching to the latter option fixed the issue.
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
}