Program to convert times from 24hr to 12hr clock

My latest attempt at a programming project from chapter 4 of Absolute C++.

Could you guys let me know what's right/wrong with my code? It runs fine, and achieves the objective, but I'd love to know if I could be improving it.

One thing I did notice: what's the difference between using "call-by-reference" as I am below, and simply using global variables? Would either achieve the same thing here?

Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*Write a program that converts from 24-hour notation to 12-hour notation. For
example, it should convert 14:25 to 2:25 P.M. The input is given as two integers.
There should be at least three functions: one for input, one to do the conversion,
and one for output. Record the A.M./P.M. information as a value of
type char, ā€™Aā€™ for A.M. and ā€™Pā€™ for P.M. Thus, the function for doing the conversions
will have a call-by-reference formal parameter of type char to record
whether it is A.M. or P.M. (The function will have other parameters as well.)
Include a loop that lets the user repeat this computation for new input values
again and again until the user says he or she wants to end the program.*/

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

//all functions call-by-reference to allow them to modify variables directly
void input(int&, int&, char&);
void convert(int&, int&, char&);
void output(int&, int&, char&);

int main()
{
	int hours, minutes;
	char ampm; //this will hold a character that allows the program to tell if it's AM or PM
	char again; //store user's choice if they want to re-run program
		
	//loop to re-run program as long as user wants
	do
	{
		//call the 3 fucntions in turn
		input(hours, minutes, ampm);
		convert(hours, minutes, ampm);
		output(hours, minutes, ampm);
		
		cout << endl << "Enter Y to run again, any other key to exit: ";
		cin >> again;
	}
	while(again == 'y' || again == 'Y');
	
	return 0;
}

void input(int& hours, int& minutes, char& ampm)
{
	//this loop makes sure value entered is legal for hours(i.e. 23 or below)
	do
	{
		cout << "Enter hours: ";
		cin >> hours;
		if(hours > 23) cout << "Please enter a value between 0 and 23" << endl;
	}
	while(hours > 23);
	
	//this loop makes sure value entered is legal for minutes (i.e. 59 or below)
	do
	{
		cout << "Enter minutes: ";
		cin >> minutes;
		if(minutes > 59) cout << "Please enter a value between 0 and 59" << endl;
	}
	while(minutes > 59);
}

void convert(int& hours, int& minutes, char& ampm)
{
	//set AM/PM flag to PM if hour is 13 onwards, and set hours to 12hr format
	if(hours > 12)
	{
		hours = hours - 12;
		ampm = 'p';
	}
	else if(hours == 12) ampm = 'p'; //set AM/PM flag to PM if hour is 12 exactly, since 12 lunch time is classed as PM
	else ampm = 'a'; //if neither of above true, must be AM
}

void output(int& hours, int& minutes, char& ampm)
{
	if(ampm == 'p')
	{
		if(minutes < 10) cout << hours << ":0" << minutes << " P.M."; //adds leading 0 if minutes is 1-9
		else cout << hours << ":" << minutes << " P.M.";
	}
	else
	{
		if(minutes < 10) cout << hours << ":0" << minutes << " A.M."; //adds leading 0 if minutes is 1-9
		else cout << hours << ":" << minutes << " A.M.";
	}
}
The difference is that global variables are frowned upon and references are recommended. However, if you
are learning about references, then you need to learn about the "const" keyword also. For example, since
output() does not intend to modify the contents of any of its parameters, the parameters should be declared
as const references, which is the same as passing by value. Passing by value these parameters would be even
better than const reference, since there is a runtime penalty to access a reference variable (references are
implemented by the compiler essentially as pointers).

Now to comment on your code:
input() takes an ampm parameter but never looks at it or uses it.
You do not check for input of negative numbers.
You do not handle invalid input such as "fdhauklfhdas:" for the number of hours.
The two do...while loops in input() are so similiar in what they do, that I would consider trying to make a common function out of them.
You could reduce convert() to two lines of code if you think about it a little more. ampm should be 'p' if hours >= 12, otherwise 'a',
and you can use modulus to convert hours to the range [0...12].
You can make output() simpler by delaying the ampm check to the last minute (which is when you output either AM or PM).
Topic archived. No new replies allowed.