break outside a loop and a switch

S

serrand

Could someone tell me a beautiful way to exit from a switch and a loop in one statement ...
without using a goto... and if possible without using an auxiliary variable as i did...

int res;
while (1)
{
res = 0;
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when recieving message : %d", errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin"))
printf ("Admin d'ont manage bad formatted messages...\n");
else
switch (rq_resa.rep)
{
case 'q':
res = working_q();
manage_error (res);
break;
case 'f':
res = working_f();
manage_error (res);
break;
default:
printf ("This function is not yet implemented...\n");
}
if (res) break;
}

all ideas welcome,

Xavier
 
E

Eric Sosman

serrand said:
Could someone tell me a beautiful way to exit from a switch and a loop
in one statement ...
without using a goto... and if possible without using an auxiliary
variable as i did...

int res;
while (1)
{
res = 0;
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when recieving message : %d",
errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin"))
printf ("Admin d'ont manage bad formatted messages...\n");
else
switch (rq_resa.rep)
{
case 'q':
res = working_q();
manage_error (res);
break;
case 'f':
res = working_f();
manage_error (res);
break;
default:
printf ("This function is not yet implemented...\n");
}
if (res) break;
}

all ideas welcome,

Here's a possibility:

while (1) {
...
switch (rq_resa.rep) {
case 'q':
res = working_q();
if (res == 0)
continue;
break;
case 'f':
res = working_f();
if (res == 0)
continue;
break;
...
}
manage_error (res);
break;
}

However, I would not recommend using this pattern
indiscriminately. Other programmers -- perhaps yourself
in six months' time -- are likely to find the control flow
confusing and contrary to the usual expectations of the
way `switch' behaves. When you confuse the programmer
(perhaps yourself), you increase the chance of introducing
errors during "routine" maintenance. There's nothing wrong
with the pattern in your original code, and the "auxiliary"
variable seems to be necessary anyhow.

Another way to rearrange your original might go something
like this:

do {
...
switch (rq_resa.rep) {
case 'q':
res = working_q();
break;
case 'f':
res = working_f();
break;
...
}
} while (res == 0);
manage_error (res);

.... and I think this is clearer than my abuse of `continue',
but perhaps a little less clear than your original.
 
H

Haroon Shafiq

serrand said:
Could someone tell me a beautiful way to exit from a switch and a loop in one statement ...
[snip]
beauty is in the eye of the beholder...
 
V

Vladimir S. Oka

Eric said:
serrand wrote:
Another way to rearrange your original might go something
like this:

do {
...
switch (rq_resa.rep) {
case 'q':
res = working_q();
break;
case 'f':
res = working_f();
break;
...
}
} while (res == 0);
manage_error (res);

... and I think this is clearer than my abuse of `continue',
but perhaps a little less clear than your original.

I'd say that this is the "correct" way of representing what OP wanted,
and one of the cases where do { } while() is a natural choice.

Cheers

Vladimir
 
V

Vladimir S. Oka

Vladimir said:
Haroon said:
Could someone tell me a beautiful way to exit from a switch and a
loop in one statement ...
[snip]
beauty is in the eye of the beholder...

No:

Beauty is the eye of the beer-holder... ;-)

Obviously, "in the eye", although the above could have some merit, too.

Cheers

Vladimir
 
H

Herbert Rosenau

Could someone tell me a beautiful way to exit from a switch and a loop in one statement ...
without using a goto... and if possible without using an auxiliary variable as i did...

Some very little changes:

/*
*/
int res = 0; /* initialise variables during definition makes
things easier */
/*
while (1)
*/

while (!res)
{ /* superflous
res = 0; */
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when recieving message : %d", errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin")) {
printf ("Admin d'ont manage bad formatted messages...\n");
res = 4712; /* some value reprenting this error if it is
one */
break; /* or when this is not really an error then
continue; */
/* and no change to res */
}
else /* will be superflous now */
switch (rq_resa.rep)
{
case 'q':
res = working_q(); /*
manage_error (res); */
break;
case 'f':
res = working_f(); /*
manage_error (res);
/* set error code like above instead */
*/
break;
default:
printf ("This function is not yet implemented...\n");
res = 4711; /* some value representing this error
(if it is one */
/* unneeded as the while makes the right thing.
if (res) break; */
}
manage_error(res); /* will do nothing when res is 0 (NO_ERROR) */
all ideas welcome,

There is a flaw anyway above: You would set an errorcode and break the
while whenever something gets fault. manage_error() should know that
it has only to print a single error message and do exactly that.

That is whenever one case is finished good: continue;
bad: break; (the switch)

Another possiblity is to move the whole switch (maybe inclusive the
while when it is really needed) into an own function and use "return
errorcode" whenever you have to break out and return 0 otherwise,

I prefere this because
- the new function will break its run whenever an error is dedected
so we know inside the function that anything goes well for now.
You would not even think on goto.
- anything that is to do when the switch is finished can be done there
without breaking the flow as we know that the calle gets informed
immediately about the error and only when there is no error the flow
gets on.
- I love short functions holding only organizational things where
the real work gets hidden. I learned that in the time an I8088 was
quick like a rocket.


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
J

Joe Wright

Vladimir said:
Vladimir S. Oka wrote:

Haroon Shafiq wrote:

serrand wrote:

Could someone tell me a beautiful way to exit from a switch and a
loop in one statement ...

[snip]
beauty is in the eye of the beholder...

No:

Beauty is the eye of the beer-holder... ;-)


Obviously, "in the eye", although the above could have some merit, too.

Cheers

Vladimir
And often best observed through the bottom of the beer-glass. :)
 
R

Rod Pemberton

serrand said:
Could someone tell me a beautiful way to exit from a switch and a loop in one statement ...
without using a goto... and if possible without using an auxiliary variable as i did...

int res;
while (1)
{
res = 0;
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when recieving message : %d", errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin"))
printf ("Admin d'ont manage bad formatted messages...\n");
else
switch (rq_resa.rep)
{
case 'q':
res = working_q();
manage_error (res);
break;
case 'f':
res = working_f();
manage_error (res);
break;
default:
printf ("This function is not yet implemented...\n");
}
if (res) break;
}

all ideas welcome,

Xavier

Like Sosman, I think 'continue' is the way to go. All loopable cases hit a
'continue' and all exitable cases hit a 'break' 'break'. Also, there is no
use of a temporary variable 'res'. Unfortunately, without the temporary
variable, manage_error() always gets called. Also, it's 'receiving', the
'i' and 'e' are switched. Also, it's "doesn't" not "d'ont".

while (1)
{
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when receiving message : %d",
errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin"))
{
printf ("Admin doesn't manage bad formatted messages...\n");
continue;
}
else
switch (rq_resa.rep)
{
case 'q':
manage_error (working_q());
break;
case 'f':
manage_error (working_f());
break;
default:
printf ("This function is not yet implemented...\n");
continue;
}
break;
}


Rod Pemberton
 
N

Nelu

serrand said:
Could someone tell me a beautiful way to exit from a switch and a loop
in one statement ...
without using a goto... and if possible without using an auxiliary
variable as i did...

int res;
while (1)
{
res = 0;
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when recieving message : %d",
errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin"))
printf ("Admin d'ont manage bad formatted messages...\n");
else
switch (rq_resa.rep)
{
case 'q':
res = working_q();
manage_error (res);
break;
case 'f':
res = working_f();
manage_error (res);
break;
default:
printf ("This function is not yet implemented...\n");
}
if (res) break;
}

all ideas welcome,

Xavier

a while loop is executed as long as the condition is true.
I do not consider while(1) an elegant way to program.
It may make your code faster and that's fine if that's what you
want, but I would use a variable that can change to false
when you want it to.
 
P

Peter Nilsson

serrand said:
Could someone tell me a beautiful way to exit from a switch and a loop in one
statement ...
Yes...

without using a goto...

What have you got against goto?
 
C

clayne

Nelu said:
a while loop is executed as long as the condition is true.
I do not consider while(1) an elegant way to program.
It may make your code faster and that's fine if that's what you
want, but I would use a variable that can change to false
when you want it to.

It's not about elegant - it's about get it done.

Anyways, why not state what you wanted to state?

while (res) { res = blah(); }
 
N

Nelu

clayne said:
It's not about elegant - it's about get it done.
Yes, it is about getting it done but I replied to the elegant
way question.
Anyways, why not state what you wanted to state?

while (res) { res = blah(); }
I guess it would've been easier to do just that. I don't know
why I didn't do it.
 
N

Neil

How about:

int res = 0 ;

while (!res)
{
res = 0;
if ((i = msgrcv (msqid, &rq_resa, SZ_MsgSrcResa, pid(), 0) == -1)
{
aff_erreurs ("msgrcv", "Error when recieving message : %d",
errno);
continue;
}
if (strcasecmp (rq_resa.mess,"admin"))
printf ("Admin d'ont manage bad formatted messages...\n");
else
switch (rq_resa.rep)
{
case 'q':
res = working_q();
manage_error (res);
break;
case 'f':
res = working_f();
manage_error (res);
break;
default:
printf ("This function is not yet implemented...\n");
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,573
Members
45,046
Latest member
Gavizuho

Latest Threads

Top