Changing while loop to accommodate two situations - c++

Suppose I have a while loop that depends on two separate inputs. In situation one, the while loop will take the value 1, and in situation two, it should take !cin.eof(). Is there a way I can do this efficiently? To be more concise:
string hello;
cin >> hello;
if(hello == "one")
{
//make the while loop depend on value 1
}
else if(hello == "two")
{
//make the while loop depend on value !cin.eof()
}
while(/*depends on above conditional*/)
{}
I don't want to do something like:
if(hello == "one)
{
while(1){}
}
else if(hello == "two")
{
while(!cin.eof){}
}
because the while loop essentially does the same thing in each situation.

For readability and in the interest of cohesion, I think you should move the contents of your loop into a separate function:
void DoSomething() { /* ... */ }
// ...
if(hello == "one)
{
while(1){ DoSomething(); }
}
else if(hello == "two")
{
while(!cin.eof){ DoSomething(); }
}
It's easier to see that the different while loops are doing the same thing but their conditions are different.

I believe you're looking for something like this:
while((hello == "one") || (hello == "two" && !cin.eof)) {
}
This code will do what you want, because it checks 'is the variable "one"? If so, keep executing. If it's not, it'll check: Is the variable "two"? If so, it'll check for cin.eof.
If it's neither, the loop won't execute. (the && 1 in the first condition was omitted, because it's always 'true', equalling and infinite loop)
Edit:
To simplify things, you may want to consider this code (as suggested in the comments):
bool HelloIsOne = (strcmp(hello, "one") == 0);
bool HelloIsTwo = (strcmp(hello, "two") == 0);
while(HelloIsOne || HelloIsTwo && !cin.eof) {
}
The brackets, which I placed in the previous example are actually unnecessary, because && binds stronger than ||, but they help the general clarity of the code.

Simply use or (||) as a condition in the while loop. Set the first condition if(hello == "one"). Now you have a while loop that will loop if one of the conditions is true.
bool value = hello == "one";
while (value || !cin.eof) {}

If you're using C++11:
#include <functional>
auto check = (hello == "one") ? []() bool -> { return 1; } :
[]() bool -> { return !cin.eof(); };
while(check) {
};

How about this:
switch(hello)
{
case 'one':
{
for(; 1; );
{
// your loop here
}
break;
}
case 'two':
{
for(;!cin.eof; )
{
// your other loop here
}
break;
}
default:
{
cout << " shouldnt get here unless bad user input" << endl;
break;
}
}

You can do something like this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string hello;
cin >> hello;
while(hello=="one"?1:(!cin.eof()))
{
//do stuff
}
return 0;
}
It checks if the string hello is "one" and if it's true, the condition of the while is 1, else it is !cin.eof() as you wanted.

Related

c++ macro using variable from an other macro

I need to make foo compile by implementing the macros for it:
int foo(std::string tag)
{
SWITCH_STRING(tag)
{
STRING_CASE(a)
{
return 1;
}
STRING_CASE(b)
{
return 2;
}
STRING_CASE(abc)
{
return 3;
}
STRING_ELSE
{
return -1;
}
}
}
I would like to use the tag parameter in SWITCH_STRING(tag) and compare it to the letter parameter in STRING_CASE(letter), to implement this switch like syntax, I'm stuck for a while and new to macros in c++ could you offer a solution to how to implement the macros please?
#include <iostream>
#include <string>
// Write macros here |
#define SWITCH_STRING(tag)
#define STRING_CASE(letter) letter == tag ? true : false
#define STRING_ELSE
I have to admit: Macros can be fun. We all should know that they should be avoided. Though, as this is an exercise about macros, we can put the discussion whether to use a macro or not aside.
The point of the exercise is that you cannot (directly) switch on a std::string. This answer shows how this limitation can be worked-around. Being required to write exremely verbose repetetive code, the macro is kind of justified. For the sake of completeness I want to add how it can be solved using your original approach, using a series of if instead of the switch.
First, I write the function that does what is asked for without any macro involved:
int foo(std::string tag)
{
std::string& temp = tag;
{
if (temp == "a")
{
return 1;
}
if (temp == "b")
{
return 2;
}
if (temp == "abc")
{
return 3;
}
{
return -1;
}
}
}
It isnt that nice that it uses ifs not else if that should be prefered for mutually exclusive cases. However, as each case returns, the result wont differ (if that isnt the case, you'll have to add some goto vodoo as outlined in the other answer). Having that, it is straightforward to see what macros are needed:
#define SWITCH_STRING(tag) std::string& temp = tag;
#define STRING_CASE(X) if (temp == #X)
#define STRING_ELSE
This kind of answers your question about how to use the parameter of one macro in a second one: You don't. Instead you can use a reference whose name does not depend on the actual name of tag anymore.
Full example
What you might do to switch on string:
constexpr std::size_t myhash(std::string_view) { /* .. */ }
int foo(const std::string& tag)
{
switch (tag)
{
case myhash("a"): { return 1; }
case myhash("b"): { return 2; }
case myhash("abc"): { return 3; }
default: { return -1; }
}
}
That doesn't need MACRO.
If you have collisions with your cases, compilation would fail (same value in switch)
and you will need another hash function.
If you want to prevent collisions (from input string), you might do:
constexpr std::size_t myhash(std::string_view) { /* .. */ }
int foo(const std::string& tag)
{
switch (tag)
{
case myhash("a"): { if (tag != "a") { goto def; } return 1; }
case myhash("b"): { if (tag != "b") { goto def; } return 2; }
case myhash("abc"): { if (tag != "abc") { goto def; } return 3; }
default: { def: return -1; }
}
}
which might indeed be less verbose with MACRO
#define CaseHash(str, c) case myhash(c): if (str != c) { goto def; }
#define DefaultHash default: def
to result to
constexpr std::size_t myhash(std::string_view) { /* .. */ }
int foo(const std::string& tag)
{
switch (tag)
{
CaseHash(tag, "a") { return 1; }
CaseHash(tag, "b") { return 2; }
CaseHash(tag, "abc") { return 3; }
DefaultHash: { return -1; }
}
}

Evaluate expression in a string recursively

Lets say we would like to evaluate expressions in a string. Expressions represented by (###) for simplicity in the example. We only count the hashtags in the example for simplicity. Expressions can be nested.
#include <iostream>
#include <string>
std::string expression{ "(###(##)#(###)##)" };
int countHash(std::string::iterator stringIterator, std::string::iterator stringEnd)
{
int result = 0;
while (stringIterator != stringEnd)
{
if (*stringIterator == '#')
{
result += 1;
}
else if (*stringIterator == '(')
{
result += countHash(++stringIterator, stringEnd);
}
else if (*stringIterator == ')')
{
return result += countHash(++stringIterator, stringEnd);
}
++stringIterator;
}
return result;
}
int main()
{
std::cout << countHash(expression.begin(), expression.end()) << std::endl;
return 0;
}
Output: 51
Expexted output: 11
So my problem is when I return from the recursive call the iterator is not updated. It is behind. The processing goes through parts of the string multiple times. How should I handle this?
My main goal by the way is to be able to evaluate expressions like this:
std::string expr = "(+1 (+22 3 25) 5 (+44 (*3 2)))";
EXPECT(106== evalExpression(expr.begin(), expr.end()));
Thanks.
EDIT:
I updated my question based on the suggestions in the comments.
#include <string>
#include <iostream>
std::string expression{ "#####-###-##" };
int countHash(std::string::iterator & stringIterator, std::string::iterator stringEnd)
{
int result = 0;
while (stringIterator != stringEnd)
{
switch (*stringIterator++)
{
case '#':
result += 1;
break;
case '-':
result += countHash(stringIterator, stringEnd);
break;
default:
// indicate error ?
break;
}
}
return result;
}
int main()
{
std::string::iterator b = expression.begin();
std::cout << countHash(b, expression.end()) << std::endl;
return 0;
}
OK so as I edited my original question, here is a solution for that:
#include <iostream>
#include <string>
std::string expression{ "(###((##)#)(#(#)#)#(#))" };
int countHash(std::string::iterator& stringIterator, std::string::iterator stringEnd)
{
int result = 0;
while (stringIterator != stringEnd)
{
if (*stringIterator == '#')
{
result += 1;
}
else if (*stringIterator == '(')
{
result += countHash(++stringIterator, stringEnd);
continue;
}
else if (*stringIterator == ')')
{
++stringIterator;
return result;
}
++stringIterator;
}
return result;
}
int countHash(std::string expression)
{
auto it = expression.begin();
return countHash(it, expression.end());
}
int main()
{
std::cout << countHash(expression) << std::endl;
return 0;
}
Output: 11
So one important thing was that you need to pass the string by reference to avoid processing the same segments of the string multiple times after you return from your recursive calls.
What I also had difficulty with is that you need to do a continue after the recursive call in my while loop. This is because you don't want to increment stringIterator after your return from the recursive call.
You could also do this with the post increment operator and with a switch-case as #bruno did it in his answer. That was the insight for me. If you are not only checking for characters switch-case is not possible though. You could use a do-while loop but I don't like that.
On more important thing was that you need to increment your iterator before returning from the ) branch. That is because that's the end of an expression and if it was a recursive call you want to go on with the expression on the caller side.
One other problem was that you cant pass expression.begin() if your function takes a reference to iterator.
For the
std::string expr = "(+1 (+22 3 25) 5 (+44 (*3 2)))";
expression my solution is available at https://github.com/bencemeszaroshu/expeval/blob/master/expeval/expeval.cpp. I don't like it as it is now but I will try to improve it later. (Happy to hear suggestions.) It is working however. Thanks everyone for your help, I'm marking #bruno answer as accepted because it helped me the most.

Am I using function pointers correctly?

I have a function that looks something like this in pseudocode:
std::string option = "option1" // one of n options, user supplied
for (int i = 0; i < 100000; i++) {
if (option == "option1") {
doFunction1a();
} else if (option == "option2") {
doFunction2a();
} else if (option == "option3") {
doFunction3a();
}
// more code...
if (option == "option1") {
doFunction1b();
} else if (option == "option2") {
doFunction2b();
} else if (option == "option3") {
doFunction3b();
}
}
However, I could avoid the repeated if statement inside the loop by doing something like this:
std::string option = "option1" // one of n options, user supplied
int (*doFunctiona)(int, int);
int (*doFunctionb)(int, int);
if (option == "option1") {
doFunctiona = doFunction1a;
doFunctionb = doFunction1b;
} else if (option == "option2") {
doFunctiona = doFunction2a;
doFunctionb = doFunction2b;
} else if (option == "option3") {
doFunctiona = doFunction3a;
doFunctionb = doFunction3b;
}
for (int i = 0; i < 100000; i++) {
doFunctiona();
// more code...
doFunctionb();
}
I realize that this will have little effect on performance (the time spend by the functions dominates the time it takes to execute the if statement).
However, In terms of "good coding practices", is this a good way to set up variable function calling? With "good" I mean: (1) easily expandable, there could easily be 20 options in the future; 2) results in readable code. I'm hoping there exists some kind of standard method for accomplishing this. If not, feel free to close as opinion based.
Just use an unordered_map and spare yourself the if-else-if-orgy:
std::unordered_map<std::string, std::vector<int (*)(int, int)>> functions;
functions.insert({ "option1", { doFunction1a, doFunction1b } });
...
const auto& vec = functions["option1"];
for(auto& f : vec) f(1, 2);
Beside using map I recommend to use std::function and lambdas which will give you more flexibility and syntax is more friendly (at least for me):
std::unordered_map<std::string, std::function<void()>> functions {
{
"option1",
[] {
functionA();
functionB();
}
},
{
"option2",
[] {
functionC();
functionD();
}
}
};
auto optionFuncIt = functions.find("option1");
if (optionFuncIt != functions.end()) {
optionFuncIt->second();
} else {
std::cerr << "Invalid option name" << std::endl;
}

Else for multiple if's

Is it possible to make multiple if's and one else for all of them without using the bool variable? I'm talking about something that works like this:
bool triggered = 0;
if (condition)
{
//code
triggered = 1;
}
if (condion2)
{
//code
triggered = 1;
}
if (!triggered)
{
//code
}
So if none of these if's happened - something happens. In pseudo-code I would write it like this:
{
if()
{
}
if()
{
}
}
else
{
}
Is there a possibility to make something similar?
No, you can't do it like that. You can do:
if (condition1 || condition2) {
if (condition1) {
//code
}
if (condition2) {
//code
}
} else {
// code
}
But this means you have to test condition1 and condition2 twice. And if there are lots of conditions, the first if will be very long.
I find your code with the triggered variable preferable. Often, there's already a variable that serves the purpose. For instance, form validation code often looks something like this:
std::string errors;
if (field1 is invalid) {
errors += "Field1 is invalid\n";
}
if (field2 is invalid) {
errors += "Field 2 is invalid\n";
}
if (errors == "") {
// process the form
} else {
// display error message
}

Refactor several nested if with same else

This is not about an existing piece of code but I'm looking for some pattern that may exist in the case that some nested if perform the same thing in their else statement.
if(condition1(a)) {
doSomethingWith1(a);
if(condition2(a)) {
doSomethingWith2(a);
} else {
elseFn();
}
} else {
elseFn();
}
The doSomethingWith... functions are changing the value of a, making it complex to have all the condition in one if.
So I'm just wondering if there is a clearer way to write it (in C, if possible).
Thanks guys
in your case, looks like the first if, if(condition1(a)), is absolutely necessary to test for the value of a before calling doSomethingWith1(a); to avoid an exception. so, no, there is no other way to do it.
if(condition1(a)) {
doSomethingWith1(a);
if(condition2(a)) {
doSomethingWith2(a);
} else {
elseFn();
}
} else {
elseFn();
}
You could just keep a count of the "doSomethings" and invoke the elseFn unless all were executed.
int count = 0;
if (condition1(a)) {
doSomethingWith1(a);
count++;
if (condition2(a)) {
doSomethingWith2(a);
count++;
if (condition2(a)) {
doSomethingWith2(a);
count++;
}
}
}
if (count < 3) {
elseFn();
}
I find it more readable, though less efficient, to double-check the first condition. This refactoring eliminates nesting, without multiple functions. It also more clearly shows three distinct paths of execution by grouping each logical path into a single code block.
if (condition1(a) && condition2(a)) {
doSomethingWith1(a);
doSomethingWith2(a);
}
else if (condition1(a)) {
doSomethingWith1(a);
elseFn();
}
else {
elseFn();
}
I don't know in C but in Java you could write this as the following:
void function(int a) {
boolean b1 = condition1(a);
if (b1) {
doSomethingWith1(a);
boolean b2 = condition2(a);
if (b2) {
doSomethingWith2(a);
}
}
if (b1 || b2) {
return;
}
elseFn();
}