Multiple choice using Enums

I want to create a class for multiple choice IO, but I am not getting the results I want. I am using enums, and it appears to work only partly, as in it takes output, but will only output for a single case of ABCDE. Is there something I am missing?
Is there an alternative way to get the job done? I know switch statements work as well, but they aren't great for reusable code.


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





//inside main 


int main()
{ 
	while (true)
	{
		IO question;
		question.CaseA = "Hello";
		question.CaseB = "bonjour";
		question.CaseC = "Hola";
		question.CaseD = "goodbye"; 
		question.CaseE = "I love you"; 
		question.SetOutput("A,B,C,D,or E");
		question.Takeinput();
		question.Caseprint();
		question.Takeinput();
		if (question.userinput == "Q")
			break;

		return 0;

	}
}
 //inside header file
#pragma once
#include <iostream>
#include <string>


using namespace std;


class IO
{ public:

	string Takeinput()
	{
		getline(cin, userinput); 
		cin.ignore('\n');
		return Stringreturn;
	}
	enum choice {
		A = 0,
		B = 1,
		C = 2,
		D = 3,
		E = 4
	};
	 
	string SetOutput(string Output) {
		cout << Output;
		return Stringreturn; 
	
	};

	string Caseprint() {
		
		if (userinput == "A"||"a" )
		{
			choice Cases = A; 
			if( Cases==A )
			{
				SetOutput(CaseA);
			}
			else (cin.ignore()); 
		}
		else if (userinput == "B"||"b")
		{
			choice Cases = B;
		 if (Cases == B)
			{
				SetOutput(CaseB);
			}
		 else(cin.ignore());
		}
		else if (userinput == "C"||"c")
		{
			choice Cases = C;
			 if (Cases == C)
			{
				SetOutput(CaseC);
			}
			 else(cin.ignore()); 
		}
		else if (userinput == "D"||"d")
		{
			choice Cases = D;
			if (Cases == D)
			{
				SetOutput(CaseD);
			}
			else(cin.ignore());
		}
		else if (userinput == "E"||"e")
		{
			choice Cases = E;
			if (Cases == E)
			{
				SetOutput(CaseE);
			}
			else(cin.ignore());
		}
		else SetOutput("error, not a choice");

		return Stringreturn; 
	}
public:

	const string Stringreturn="  "; 
	string CaseA;
	string CaseB; 
	string CaseC; 
	string CaseD; 
	string CaseE; 

	string userinput; 
	
private:
	string Output; 

	
	
	
	    
	 

};
Last edited on
(userinput == "A"||"a" )

This will ALWAYS evaluate to true, because the condition on the right hand side of the || is "a", which is considered to be true.

I expect you meant: (userinput == "A"|| userinput == "a" )
2 thread same work. keep it together please, we can help better (even if 2 different questions) if we can follow the whole topic.
I fixed the boolean issue. I simply need some help with perhaps some ways that I could better implement this approach to IO, in a more "production grade" way.
Hello Willogical,

Just reading through your code this is what I see:

Without what would be above "main" it is hard to say if you did anything wrong.

In "main" everything works down to line 19. Lines 19 - 22 all call functions that return a value, but you never collect this return value or use it.

The if statement on line 23 works fine for "Q", but for everything else the if statement will be bypassed and rhe "return" statement will end the program. The "return" statement needs to be after line 28.

In the header file:

Header should not have "include" statements. These are best left for ".cpp" files.

And using namespace std; should never be in a header file. Read this for more information. http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/

In the function "Takeinput()". The use of "std::getline(...)" is OK,but the next line, even if it would work, looks like it does, it is not needed, the "std::getline(...)" will read everything up to and including the new line, e.g., (\n). Which makes the "ignore" kind of pointless. The more used way of writing the "ignore" statement is
 
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. 

The first parameter just creates a very large number that is dependent on the computer and compiler along withe the header files used with that compiler. You can use any number you want for the first parameter. I recently had a program where I had to use "1" to make it work.

The third line returns two spaces. I am not sure why you would want to return two spaces, but you do not collect this in "main" or even use it there.

The same problem with the other two functions. You return two spaces, but never use them.

The enum "choice" can be written simply as: enum choice {A, B, C, D, E. When no value is given for the first name it starts at zero and increases by one for each successive name.

The "SetOutput" function is mostly OK except that you return two spaces that are never used.

In the if statements you have already been told how that should be written.

As I look at the line, #66, I am slowly coming to the conclusion that it will work, but I believe you do not realize what the value of "Cases" will be. Not the "A" that you might be think, but the value zero. The next if statement will always be false because "Cases" will contain a number not a letter. You may want to give this a read https://en.cppreference.com/w/cpp/language/enum It will explain what I have been saying in regards to the "enum". The call to the function "SetOutput" is not needed because you are not only sending the wrong variable to the function "CaseA" is defined as a "public" variable therefor the entire program has access to this variable, so there is no need for a function to set this variable. just use its name and set it equal to something. Although you may have a problem setting a "string' to an "enum" int. You will have to change the "int" to a "string" first.

In the else part the outside set of parentheses () should be a set of curley braces {} because the {} define a block. A moot point because the "cin.ignore" is not needed as you have not used "cin" to get any input. The same is true for the other "else if" and "if" statements.

Your next set of "public" variables should be under the "private" section. As "public' variables the whole program has access to them and this tends to defeet the purpose of the class protecting the variables.

Without the missing pieces I will have to guess at what is need to get the program working so I can test it.

Hope that helps,

Andy

Tweaked a few things, added namespace indication and setters. Now I think I might need to pass by reference to make this work. From there I would like suggestions on how to expand this code to do something useful like a console text-based rpg game.

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
// in main
int main()
{ 
	while (true)
	{
		IO question;
		question.SetA("Hello"); 
		question.SetB("I like cheese");
		question.SetC(" I love you");
		question.SetD("Goodbye, Donald");
	    question.SetE("Candy is healthier than crystal meth.");
		question.SetOutput("A,B,C,D,or E");
		question.Takeinput();
		question.Caseprint();
		
		

		

	}
   return 0;
}

#pragma once
#include <iostream>
#include <string>




class IO
{ public:

	std::string Takeinput()
	{
		std::cin>>userinput; 
		
		return Stringreturn;
	}
	enum choice { A, B, C, D, E };
	 
	std::string SetOutput(std::string Output) {
		std::cout << Output;
		return Stringreturn; 
	    
	};
	std::string SetA(std::string CaseA)
	{
		Output = CaseA; 
		return CaseA; 
	}
	std::string SetB(std::string CaseB)
	{
		Output = CaseB; 
		return CaseB;
	}
	std::string SetC(std::string CaseC)
	{
		Output = CaseC;
		return CaseC;
	}

	std::string SetD(std::string CaseD)
	{
		Output = CaseD; 
		return CaseD;
	}
	std::string SetE(std::string CaseE)
	{
		Output = CaseE; 
		return CaseE;
	}

	std::string Caseprint() {
		
		if (userinput == "A"||userinput=="a" )
		{
			choice Cases = A; 
			if( Cases==A )
			{
				SetOutput(CaseA);
			}
			
		}
		else if (userinput == "B"||userinput=="b")
		{
			choice Cases = B;
		 if (Cases == B)
			{
				SetOutput(CaseB);
			}
		 
		}
		else if (userinput == "C"||userinput=="c")
		{
			choice Cases = C;
			 if (Cases == C)
			{
				SetOutput(CaseC);
			}
			  
		}
		else if (userinput == "D"||userinput=="d")
		{
			choice Cases = D;
			if (Cases == D)
			{
				SetOutput(CaseD);
			}
			
		}
		else if (userinput == "E"||userinput=="e")
		{
			choice Cases = E;
			if (Cases == E)
			{
				SetOutput(CaseE);
			}
			
		}
		else SetOutput("error, not a choice");

		return Stringreturn; 
	}
public:

	const std::string Stringreturn="  "; 
	
	std::string userinput; 
	
private:

	std::string CaseA;
	std::string CaseB;
	std::string CaseC;
	std::string CaseD;
	std::string CaseE;

	std::string Output; 

	
	
	
	    
	 

};

Last edited on
Topic archived. No new replies allowed.