In my example code here's some ways to avoid using goto in this fragment:
Code:
if ( scanf ( "%lf%c + %lf = %lf", &a, &y, &b, &c ) != 4 )
{
invalid_input:
puts ( "Invalid input!" );
return 1;
}
// NOTE: It is OK to use goto (in this context)!
if ( y != VARIABLE_NAME )
goto invalid_input;
1- Replicate the same block in the second if:
Code:
if ( scanf ( "%lf%c + %lf = %lf", &a, &y, &b, &c ) != 4 )
{
puts ( "Invalid input!" );
return 1;
}
if ( y != VARIABLE_NAME )
{
puts ( "Invalid input!" );
return 1;
}
This, in an unoptimized compilation, will make the program a little bigger (2 calls to puts).
2- Use setjmp/longjmp:
Code:
jmp_buf jb;
if ( setjmp( jb ) )
{
puts( "Invalid input!" );
return 1;
}
...
if ( scanf ( "%lf%c + %lf = %lf", &a, &y, &b, &c ) != 4 )
longjmp( jb, 1 );
if ( y != VARIABLE_NAME )
longjmp( jb, 1 );
This will create a more complex code (slower and bigger).
3- Use a helper function which never returns
Code:
static void invalid_func( void )
{
puts( "Invalid input!" );
exit(1);
}
...
int main( void )
{
...
if ( scanf ( "%lf%c + %lf = %lf", &a, &y, &b, &c ) != 4 )
invalid_func();
if ( y != VARIABLE_NAME )
invalid_func();
Solution 2 and 3 breaks the conditions of the exercise (only to use stdio.h!) and create a bigger code.
If you want to avoid goto, use solution #1.
With solution 3 the compiler can decide to make the function inline, which is more or less equivalent to solution 1, to avoid inlining you'll need to use a compiler extenstion. For GCC:
Code:
__attribute__((noinline))
static void invalid_func( void ) { ... }
But, since this is not standard, It can be unacceptable to solve the problem at hand.