Using || (or) with cin.ignore ?

Hi, I have two characters that may need to be ignored up to. The problem is, it can be one or the other (never both). I'm forced to use two if statements in order to account for ignoring both. However, I'll be able to condense the code if there's a way to allow cin.ignore to ignore up to one value or another. For example :

 
  std::cin.ignore(100, 'a'||'A')


Now, that code obviously doesn't work, but it shows what I'm trying to do. So if something like that is possible, it would be a great help, thanks !
Hello zapshe,

This is a nice idea, but as you have found it will not work. The 'a'||'A' will return either 0 or 1 (true or false) not what you want. The second parameter need to be a single "int" Not seeing the whole code I was thinking that the "peek" function may have some use along with an if/else statement then maybe use a variable for the second parameter of the ignore.

I would have to do some testing to see if this would work.

Ii would help to know what happens before the "std::cin.ignore()".

I will see if I can come up with anything.

You may find this useful http://www.cplusplus.com/reference/istream/istream/ignore/

Hope that helps,

Andy
Hello zapshe,

After working with different methods I found the string function "find_first_of("aA") to be useful. Not sure if this is something you could use.

Using "regex" may also be of some use. I will have to look into that.

Just some thoughts for now.

Andy
Not sure, but maybe you could write your own?

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
#include <iostream>
#include <sstream>
#include <string>
using namespace std;


void myIgnore( istream &strm, int n = 1, string delim = "\n" )
{
   if ( n <= 0 ) return;
   char c;
   while ( strm.get( c ) && --n && delim.find( c ) == string::npos );
}


int main()
{
   stringstream ss( "There is a tide in the affairs of men, which, taken at the flood, leads on to fortune;" );
// istream &ss = cin;
   char c;

   ss >> c;   cout << "Character read = " << c << '\n';
   myIgnore( ss, 1000, "mM" );
   ss >> c;   cout << "Character read = " << c << '\n';
   myIgnore( ss, 3   , "fF" );
   ss >> c;   cout << "Character read = " << c << '\n';
   myIgnore( ss, 1000, "!$" );
   cout << "Condition of the stream is " << (bool)ss << '\n';
}

Thanks Handy Andy and LastChance for the replies. The code before the ignore statement probably wont be that useful- But here it is :

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
int main()
{
	std::cout << "Press / To Exit." << '\n' << "Use 'a' To Symbolize Previous Value." << '\n' << "----------------------------------------" 
	<< '\n';
Equation:
	std::cout << "Type In Equation: ";
	char e;
	std::cin >> e;

	if (e == '/') // Pressing "/" Stops Program 
	{
		std::cout << '\n';
		return 0;
	}
	if (e == 'a') // Input "a" Will Give You You're Previous Answer To Work With
	{
		if (a == 0)
		{
			std::cout << '\n' << "No Previous Value" << '\n' << '\n';
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<int>::max(), '\n');
			goto Equation;
		}
		x = a; 
		std::cin.putback(e);
		std::cin.ignore(10, 'a');
		goto Op;
	}
	if (e == 'A') // Input "A" Will Give You You're Previous Answer To Work With
	{
		if (a == 0)
		{
			std::cout << '\n' << "No Previous Value" << '\n' << '\n';
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<int>::max(), '\n');
			goto Equation;
		}
		x = a;
		std::cin.putback(e);
		std::cin.ignore(10, 'A');
		goto Op;
	}

		std::cin.putback(e);

Start:
	std::cin >> x;
	Op:
	std::cin >> z;
	if (z == '!') // To Skip Getting A "y" Value For Factorials
	{
		goto Operation;
	}
	std::cin >> y;


As you can see, the code asks for the char e (But since this is a calculator the user will type in an equation of they don't want to exit) - and if the input isn't "/" or "a/A", then it puts that input back into the buffer to be used with other variables in the calculator.

However, I wanted to be able to allow for usage of one's previous answer. For example 1 - 2. The answer is -1, but then you want to use that previous answer in your new equation without typing it all back in. So I made the calculator take the input "a/A" for char e as well. When they press that, the variable "x" (the first number in their calculations) becomes their previous answer. Then the program will put the whole char e value back into the buffer (Including "a/A" which we don't want !) Therefore, I needed the ignore statements to ignore those a characters since they wont be part of the equation and have already done their job.

I tried using "find_first_of("aA")" but it was undefined, even with #include <regex> .


As for LastChance, I'm still new with all this so I'm not 100% sure what your code does. Perhaps you could walk me through it?

Thanks everyone for their posts !
As an example,
myIgnore( ss, 1000, "mM" );
is intended to do what you indicated in your post: ignore characters from stream ss until either 1000 characters have been read, it finds ANY of the characters in the string (here, m or M), or it reaches the end of the stream.

I'm afraid that the logic of your actual code is beyond me, so I'll leave it at that.
Hello zapshe,

For an earlier question the "str.find_first_of()" is from the "string" header file not "regex" header file. "str" is any variable that you have defined as a "std::string".

Using "regex" is a completely different approach to the problem.

Looking at you code which I do not believe it complete, but I did manage to get it to compile and run.

When it did run I found that you prompt the user for a formula, but you try to put all of this into a single character. This may work as long as you only use single digit numbers and the next two "cin"s pick up the sign and last digit. I have not looked into this yet.

I think you have a good idea for your program, going about it the wrong way.

A couple of notes on what I see and do not see. If "a", "x", "y" and "z" are defined as global variables I would put them in main and pass them to any function that you may code that would need them.

"e" is defined as a "char". This only holds one character, so if the first number is 100 only the 1 will be extracted and the 0 0 would end up in your next two variables if possible. I would consider making "e" a std::string" and then pick that apart into what you need.

Another option is to input (number - char - number) separately. Or you could put the (char) first and then get the numbers. I say "numbers" because they could be "int"s or "double"s. Actually typing in "5 + 5" to "std::cin >> num >>char >>num" would get a number, sign and number into three different variables at one time. If you enter the "char" first you can pick up on the input being "!" and only request one number from the user.

The use of "goto"s is bad form, bad idea and bad programming which should be avoided at all times. The use of "goto"s is known as spaghetti code and like spaghetti you are jumping all over your code. This may work, but some day it will lead to a problem. most "goto"s can be replaced with a while loop or more likely a do/while loop.

Right now your program is trying to do something it is not designed to do and you are trying to fix parts that are not broke.

I would step back and take a look at what you have done and see if you can come up with something different. Programs that I have seen like this tend to use switch/case statements and functions to deal with the sign and then the math.

Hope that helps,

Andy
The code for making "myVoid" would be counterproductive for me as the whole reason I want such a method is to have less code. That method will cause me to have to deal with the new code and such - But thanks for the input!

Moreover, Sorry - I seem to have caused some confusion. I put part of the code on there (What was before the cin.ignore) to help visualize what was happening. The code is already done and completely working fine. If you want to see the whole code - here it is :

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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// It's Time To Calculate The Calculations With A Calculator !

#include "stdafx.h"

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <iomanip>


double a;
double x;
double y;
char z;

int subtract()
{
	a = x - y;
	return a;
}

int add()
{
	a = x + y;
	return a;
}

int divide()
{
	a = x / y;
	return a;
}

int multiply()
{
	a = x * y;
	return a;
}

int power()
{
	a = pow(x, y);
	return a;
}

unsigned long long factorial(int f) //Loops Until int f = 1 
{									//Limit Is 64 Factorial
	if (f < 0)
	{
		std::cout << '\n' << "Cannot Have A Negative Factorial" << '\n' << std::endl; 
		return a = 0;
	}
	if (f > 20)
	{
		std::cout << '\n' << "Factorial Too Big!" << '\n' << std::endl;
		return a = 0;
	}
	if (f == 1) return a = 1;
	if (f == 0) return a = 1;
	else return a = f * factorial(f - 1);

}


int main()
{
	std::cout << "Press / To Exit." << '\n' << "Use 'a' To Symbolize Previous Value." << '\n' << "----------------------------------------" 
	<< '\n';
Equation:
	std::cout << "Type In Equation: ";
	char e;
	std::cin >> e;

	if (e == '/') // Pressing "/" Stops Program 
	{
		std::cout << '\n';
		return 0;
	}

	if (e == 'a') // Input "a" Will Give You You're Previous Answer To Work With
	{
		if (a == 0)
		{
			std::cout << '\n' << "No Previous Value" << '\n' << '\n';
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<int>::max(), '\n');
			goto Equation;
		}
		x = a; 
		std::cin.putback(e);
		std::cin.ignore(10, 'a');
		goto Op; //Since We Already Got Our "x" Value
	}
	if (e == 'A') // Input "A" Will Give You You're Previous Answer To Work With
	{
		if (a == 0)
		{
			std::cout << '\n' << "No Previous Value" << '\n' << '\n';
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<int>::max(), '\n');
			goto Equation;
		}
		x = a;
		std::cin.putback(e);
		std::cin.ignore(10, 'A');
		goto Op; //Since We Already Got Our "x" Value
	}
	
		std::cin.putback(e);
	

	std::cin >> x;

	if (std::cin.fail())
	{
		std::cout << '\n' << "Not A Number" << '\n' << std::endl;
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<int>::max(), '\n'); // Used When Code Returns To Equation To Clear Cin Errors/Clear Cin Values
		goto Equation;
	}

	Op:
	std::cin >> z;
	if (z == '!') // To Skip Getting A "y" Value For Factorials
	{
		goto Operation;
	}
	std::cin >> y;


	if (std::cin.fail())
	{
		std::cout << '\n' << "Not A Number" << '\n' << std::endl;
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<int>::max(), '\n'); // Used When Code Returns To Equation To Clear Cin Errors/Clear Cin Values
		goto Equation;
	}

	
Operation:
	switch (z)
	{
	case '-':
		subtract();
		std::cout << '\n' << "The Sum Is: " << std::setprecision(7) << a << std::endl;
		break;
	case '+':
		add();
		std::cout << '\n' << "The Sum Is: " << std::setprecision(7) << a << std::endl;
		break;
	case '/':
		if (x == 0 || y == 0)
		{
			std::cout << '\n' << "Not Possible" << std::endl;
			break;
		}
		divide();
		std::cout << '\n' << "The Sum Is: " << std::setprecision(7) << a << std::endl;
		break;
	case '*':
		multiply();
		std::cout << '\n' << "The Sum Is: " << std::setprecision(7) << a << std::endl;
		break;
	case 'x':
		multiply();
		std::cout << '\n' << "The Sum Is: " << std::setprecision(7) << a << std::endl;
		break;
	case '^':
		power();
		std::cout << '\n' << "The Sum Is: " << std::setprecision(7) << a << std::endl;
		break;
	case '%':
		if (x < y)
		{
			std::cout << '\n' << "Not Applicable" << std::endl;
		}
		else
		{	// Won't Work If Not Placed Here. Can't Perform % With Anything But Integers.
			int b = x;
			int c = y;
			a = b % c;
			std::cout << '\n' << "The Remainder is: " << a << std::endl;
		}
		break;
	case '!':
	{
		factorial(x);
		if (a == 0)
		{
			break;
		}
		std::cout << '\n' << "The Factorial Is: " << a << std::endl;
		break;
	}
	default:
		std::cout << '\n' << "Unknown Operation: '" << z << "'" << '\n' << '\n';
	}

	std::cin.clear();
	std::cin.ignore(std::numeric_limits<int>::max(), '\n');
	
	std::cout << '\n';

	goto Equation;

	return 0;
}



Also - I fully understand how the goto function can cause serious problems, but I feel confident that it wont get me in any trouble in THIS case. Moreover, I coded around the idea of simply being able to jump from code to code, so I'd prefer not have to tear down my code to accommodate other means of getting the same results.

Thanks lastchance and Handy Andy ! I suppose I'll have to keep the two if statements. My instincts wanted me to combine the two, but it seems it'll be more trouble than its worth. Thanks again !
Last edited on
Topic archived. No new replies allowed.