help with functions

Pages: 12
@seeplus I got an error when I tried to implement that to my code..


As my post said, you need to compile as C++20 and your c++c20 compiler needs to have implemented concepts.
closed account (9G8M4G1T)
I see..

Can someone help me incorporate this? The examples I have look at to understand
returning the value have just confused me even more.


The three overloaded input functions look like this. (Provide the correct parameter type.):
1) char input(parameter_type prompt_text, parameter_type error_message_text); // for getting a letter
2) double input(parameter_type min_number, parameter_type max_number, parameter_type prompt_text,
parameter_type error_message_text); // for getting a number
3) void input(parameter_type x, parameter_type y, parameter_type prompt_text); // for getting a point (x, y)

For char, print the prompt; get a character. If the character is valid (a-z or A-Z) return it.
If it is NOT valid, display the error message and try again. Use isalpha() to verify the character
is alphabetic. Loop until a valid character is entered.


For the number, print the prompt. As part of the prompt,
print the acceptable range (min, max) allowed for the value.


Get a value. If it is within the range, return it.
If NOT valid, print the error message and try again.
Loop until a valid (within range) number is entered.
Perhaps based upon previous code for function static:

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <iostream>
#include <cmath>
#include <string>

using namespace std;

enum Menu : char { letter = 'l', number = 'n', point = 'p', quit = 'q' };

Menu domenu() {
	char choice {};

	cout << "Options: " << letter << ")etter; " << number << ")umber; " << point << ")oint; " << quit << ")uit: ";
	cin >> choice;

	return static_cast<Menu>(choice);
}

void errorMessage() {
	cout << "This is not an option, try again!\n";
}

double distance(char c1, char c2) {
	return abs(c2 - c1);
}

double distance(double c1, double c2) {
	return abs(c2 - c1);
}

double distance(double x1, double y1, double x2, double y2) {
	return {sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))};
}

void display(const string& msg, char c1, char c2) {
	static unsigned cnt {};

	cout << "(#" << ++cnt << ") " << msg << ' ' << c1
		<< " & " << c2 << " is: " << distance(c1, c2) << '\n';
}

void display(const string& msg, double d1, double d2) {
	static unsigned cnt {};

	cout << "(#" << ++cnt << ") " << msg << ' ' << d1
		<< " & " << d2 << " is: " << distance(d1, d2) << '\n';
}

void display(const string& msg, double x1, double y1, double x2, double y2) {
	static unsigned cnt {};

		cout << "(#" << ++cnt << ") " << msg << "("
		<< x1 << "," << y1 << ")" << " and ("
		<< x2 << "," << y2 << ") is: "
		<< distance(x1, y1, x2, y2) << " units.\n";
}

int main() {
	for (Menu userChoice {}; userChoice != quit; ) {
		switch (userChoice = domenu()) {
			case letter:
			{
				char c1 {}, c2 {};

				cout << "Enter first letter (a to z): ";
				cin >> c1;

				cout << "Enter second letter (a to z): ";
				cin >> c2;

				display("The distance between letters", c1, c2);
			}
				break;

			case number:
			{
				double x {}, y {};

				cout << "Enter first value (-100, 100): ";
				cin >> x;

				cout << "Enter second value (-200, 200): ";
				cin >> y;

				display("The units between", x, y);
			}
				break;

			case point:
			{
				double x1 {}, x2 {}, y1 {}, y2 {};

				cout << "Enter the first point (x1): ";
				cin >> x1;

				cout << "Enter the first point (y1): ";
				cin >> y1;

				cout << "Enter the second point (x2): ";
				cin >> x2;

				cout << "Enter the second point (y2): ";
				cin >> y2;

				display("The straight line distance between points", x1, y1, x2, y2);
			}
				break;

			case quit:
				cout << "Goodbye!\n";
				break;

			default:
				errorMessage();
				break;
		}
	}
}

Last edited on
closed account (9G8M4G1T)
thank you @seeplus

If anyone can help me with this error in my code where it only measures the distance correctly
when both letters are either entered in lowercase or uppercase:
Options: l)etter; n)umber; p)oint; q)uit: l
Enter first letter (a to z): A
Enter second letter (a to z): c
(#1) The distance between letters A & c is: 34


I have to add three overloaded distance functions that need to look like this:
1) int dist(char a, char b); // return the distance between two letters (a-z)
2) double dist(double d1, double d2); // return the distance between two numbers
3) double dist(double x1, double y1, double x2, double y2); // return distance between two points.

Which should fix the problem but I'm not sure where to add them
For input functions and treating upper/lower case as the same, possibly:

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <iostream>
#include <cmath>
#include <string>
#include <limits>
#include <utility>
#include <cctype>

using namespace std;
using Point = std::pair<double, double>;

enum Menu : char { letter = 'l', number = 'n', point = 'p', quit = 'q' };

template<typename T = int>
auto getNum(const std::string& prm)
{
	const auto notsp {[&]() {while (std::isspace(static_cast<unsigned char>(std::cin.peek())) && std::cin.peek() != '\n') std::cin.ignore(); return std::cin.peek() != '\n'; }};
	T n {};

	while ((std::cout << prm) && (!(std::cin >> n) || notsp())) {
		std::cout << "Not a number\n";
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}

	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	return n;
}

std::string remzero(const std::string& str) {
	auto s(str);

	if (str.find('.')) {
		while (*s.rbegin() == '0')
			s.resize(s.size() - 1);

		if (*s.rbegin() == '.')
			s.resize(s.size() - 1);
	}

	return s;
}

char asUpper(char ch) {
	return static_cast<char>(std::toupper(static_cast<unsigned char>(ch)));
}

Menu domenu() {
	char choice {};

	cout << "Options: " << letter << ")etter; " << number << ")umber; " << point << ")oint; " << quit << ")uit: ";
	cin >> choice;

	return static_cast<Menu>(choice);
}

void errorMessage() {
	cout << "This is not an option, try again!\n";
}

double distance(char c1, char c2) {
	return abs(asUpper(c2) - asUpper(c1));
}

double distance(double c1, double c2) {
	return abs(c2 - c1);
}

double distance(const Point& p1, const Point& p2) {
	return {sqrt((p1.first - p2.first) * (p1.first - p2.first) + (p1.second - p2.second) * (p1.second - p2.second))};
}

void display(const string& msg, char c1, char c2) {
	static unsigned cnt {};

	cout << "(#" << ++cnt << ") " << msg << ' ' << c1
		<< " & " << c2 << " is: " << distance(c1, c2) << '\n';
}

void display(const string& msg, double d1, double d2) {
	static unsigned cnt {};

	cout << "(#" << ++cnt << ") " << msg << ' ' << d1
		<< " & " << d2 << " is: " << distance(d1, d2) << '\n';
}

void display(const string& msg, const Point& p1, const Point& p2) {
	static unsigned cnt {};

	cout << "(#" << ++cnt << ") " << msg << " ("
		<< p1.first << "," << p1.second << ")" << " and ("
		<< p2.first << "," << p2.second << ") is: "
		<< distance(p1, p2) << " units.\n";
}

char input(char, const std::string& inptxt, const std::string& errtxt) {
	char ch {};

	while ((std::cout << inptxt << " (a - z) : ") && (std::cin >> ch) && !std::isalpha(static_cast<unsigned char>(ch)))
		std::cout << errtxt << '\n';

	return ch;
}

double input(double, double minn, double maxn, const std::string& inptxt, const std::string& errtxt) {
	double no {};

	do {
		no = getNum<double>(inptxt + " (" + remzero(std::to_string(minn)) + ", " + remzero(std::to_string(maxn)) + ") : ");
	} while ((no < minn || no > maxn) && (std::cout << errtxt << '\n'));

	return no;
}

Point input(Point, const std::string& inptxt) {
	const auto x1 {getNum<double>(inptxt + " (x) : ")};
	const auto y1 {getNum<double>(inptxt + " (y) : ")};

	return {x1, y1};
}

int main() {
	for (Menu userChoice {}; userChoice != quit; ) {
		switch (userChoice = domenu()) {
			case letter:
			{
				static const auto letErr {"Not a letter"s};
				const auto c1 {input(char {}, "Enter first letter", letErr)};
				const auto c2 {input(char {}, "Enter second letter", letErr)};

				display("The distance between letters", c1, c2);
			}
			break;

			case number:
			{
				static const auto numErr {"Out of range"s};
				const auto x {input(double {}, -100, 100, "Enter first number", numErr)};
				const auto y {input(double {}, -200, 200, "Enter next number", numErr)};

				display("The units between", x, y);
			}
			break;

			case point:
			{
				const auto x {input(Point {}, "Enter the first point")};
				const auto y {input(Point {}, "Enter the second point")};

				display("The straight line distance between points", x, y);
			}
			break;

			case quit:
				cout << "Goodbye!\n";
				break;

			default:
				errorMessage();
				break;
		}
	}
}

Last edited on
> Can someone help me incorporate this?

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
#include <string>
#include <iostream>
#include <cctype>

// 1) char input(parameter_type prompt_text, parameter_type error_message_text); // for getting a letter
//               (Provide the correct parameter type.)
char get_a_letter /* input */ ( const std::string& prompt, const std::string& error_message )
{
    std::cout << "prompt: " ; // print the prompt;

    char c ;
    std::cin >> c ; // get a character.

    // If the character is valid (a-z or A-Z) return it.
    // Use isalpha() to verify the character is alphabetic.
    if( std::isalpha( static_cast<unsigned char>(c) ) ) return c ;

    // invalid character
    // If it is NOT valid, display the error message
    std::cout << "*** error ***  " << error_message << '\n' ;
    return get_a_letter( prompt, error_message ) ; // and try again.
                                                   // (Loop until a valid character is entered.)
}

// Now try writing this on your own
// 2) double input(parameter_type min_number, parameter_type max_number, parameter_type prompt_text,
//                 parameter_type error_message_text); // for getting a number
// For the number, print the prompt. As part of the prompt,
// print the acceptable range (min, max) allowed for the value.
// Get a value. If it is within the range, return it.
// If NOT valid, print the error message and try again.
// Loop until a valid (within range) number is entered. 
closed account (9G8M4G1T)
In the number option the range prints out as:

Enter first value (-100. - 100.) :
Enter second value (-200. - 200.) :

how can I change this and do I need a second error message since the range
is different?

it should look like this:

Enter first number (-100, 100):
Enter next number (-200, 200):
Last edited on
Well to change - as a delim to , as a delim just change the - of L108 above to ,

[Above code changed to reflect this and the other wording changes etc etc.]
Last edited on
closed account (9G8M4G1T)
I was testing the code and noticed that it's not taking or displaying the input correctly for the point option

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

Having this for x2 and y2 doesn't help. And the cout is correct but I can't find the error in the code..

Point input(Point, const std::string& inptxt) {
    const auto x1 {getNum<double>(inptxt + "(x) : ")};
    const auto y1 {getNum<double>(inptxt + "(y) : ")};

    return {x1, y1};



//Test output:

Options: l)etter; n)umber; p)oint; q)uit: p
Enter the first point (x) : 0
Enter the first point (y) : 3
Enter the second point (x) : 0
Enter the second point (y) : 4
(#1) The straight line distance between points(0,0) and (3,4) is: 1 units. 
Last edited on
Sorry, I messed up L69 when converting to Point. Changed above.
closed account (9G8M4G1T)
it is still printing the points incorrectly and I don't believe the error is in L69

could the error be in here?

1
2
3
4
5
6
7
            case point:
            {
                // displays message for user input
                const auto x {input(Point {}, "Enter the first point")};
                const auto y {input(Point {}, "Enter the second point")};
                display("The straight line distance between points", x, y);
            }
Last edited on
Ok. I didn't test properly. Mea Culpa. This is what happens you try to deal with multiple programs at once and have points called x and y. Doh........ Points are now called p1 and p2. Names do matter!


Options: l)etter; n)umber; p)oint; q)uit: p
Enter the first point (x) : 0
Enter the first point (y) : 3
Enter the second point (x) : 0
Enter the second point (y) : 4
(#1) The straight line distance between points (0,3) and (0,4) is: 1 units.
Options: l)etter; n)umber; p)oint; q)uit: p
Enter the first point (x) : 0
Enter the first point (y) : 3
Enter the second point (x) : 4
Enter the second point (y) : 0
(#2) The straight line distance between points (0,3) and (4,0) is: 5 units.
Options: l)etter; n)umber; p)oint; q)uit: q
Goodbye!

Last edited on
closed account (9G8M4G1T)
Ohh ok the error makes much more sense now. Thank you so much for all your help
Topic archived. No new replies allowed.
Pages: 12