Break statement not within loop or switch in C - c

I am getting this error in my C code. I don't know what I am doing wrong. If I comment this code my program works. This piece of code is inside int main().
if(argc!=2 && strcmp(argv[0],"selection-sort")==0 && strcmp(argv[1],"input.txt")==0 && strcmp(argv[2],"output.txt")==0)
{
printf("The command line arguments are correct.\n");
}
else
{
printf("The command line arguments are wrong.I am exiting.\n");
break;
}

The way it looks I think you're not in a loop but just checking args in main. You probably want something like return 1 or exit(1) instead of the break.

First of all make sure you are including the needed header files:
#include <stdio.h>
#include <stdlib.h>
The break command is used for exiting loops, you are not in a loop you are just in an else statement, you have nothing to break from. The code flow executes normally after passing that else statement. If you want to exit the program in that else statement you could do something like this:
else
{
printf("The command line arguments are wrong.I am exiting.\n");
return 1; //exit program with status 1 to indicate a non normal exit
}
Or if you want to continue the program after displaying that message you could just do this:
else printf("The command line arguments are wrong.I am exiting.\n");
//more code here
You only use break in loops like so:
while(foo) //while foo is true
{
break; //exit the loop
}

The error message in the title says it all: break can only be used to exit a loop or prevent a case from falling through. MSDN quote:
The break statement terminates the execution of the nearest enclosing
do, for, switch, or while statement in which it appears.
To leave a function use return.

Break is supposed to be used in loops.
Use a return statement, which causes execution to leave the current subroutine and resume at the point in the code immediately after where the subroutine was called (return address).

The other answers are correct, this is just a slight addition.
To return probably in this specific case you should include errno.h like this:
#include <errno.h>
And furthermore return like this:
return EINVAL;
Then you are signaling that the program is terminating due to an error and the return value specifically states that the error is invalid arguments.

'break' will only get you out of the innermost loop or switch. You can use 'return' to exit out of a function at any time.
"A break statement may appear only in an iteration statement or a switch statement, and terminates execution of the smallest enclosing such statement".
And it makes sense too - you can "escape" from a method with "return" , and you can skip code in other situations with an if/else. I don't know what a "break" outside a case would be expected to do.
'break' is really only a restricted form of 'goto' anyway. Ideally, you want a single point of exit from any block of code. You should really only use 'break' in a switch statement because that is the only way to make it work. In any other context, there are better ways to accomplish the same thing. The same applies to 'continue'.

Related

C, Call to function twice, one writes to file, one writes to terminal

fairly new to C and have a slight issue,
I have a function which is filled with 'fprintf' statements and some calculations relevant to the output.
When I call it from main() it works correctly and prints to the document, I then want to call it a second time and have the same text but only outputted to the terminal (as in printf).
I have a flag in the function parameters which would specify this choice but no way of accomplishing it aside from an if statement for every fprintf saying:
if (flag == 1)
{
fprintf(pt, "Random text...
} else {
printf("The same random text...
}
Which seems dreadfully inefficient. My other idea was to (with my little understanding of it) use #define within the function in the context:
if (flag== 1)
{
#define fprintf(pt, printf(
}
Which not only seemed very cheap but did not work.
Any ideas would be appreciated,
Thanks
How about something like this:
FILE *out=stdout;
fprintf(out,"Hello World\n");
Since this is a function, you can pass in the out pointer as an argument. When printing to the terminal, just assign stdout to it.
you could do a ternary expression using the fact that printf( is equivalent to fprintf(stdout,:
fprintf(flag == 1 ? pt : stdout, "Random text...");

Quit the whole program early in C?

Generally say I have some functions step1 step2 ... and they are called successively:
int main()
{
...
step1(); // something wrong detected and need to break out of the whole program
step2();
step3();
...
}
How can I break out from step1 and skip all the rest of code to terminate main() function?
Currently I can only think of setting a global variable like bool isErr as a flag so that
step1(); // error detected and isErr is set to 1 inside step1()
if (isErr)
return;
step2();
...
Are there better or more 'canonical' approaches?
BTW I've heard that goto is bad so I discard it :)
Use
exit(1);
The number indicates the exit status. 0 is no failure, everything larger then 0 indicates an error.
One option is to check return value of your step1() function and if it is error, just use for example return 1 in main. Using return (with appropriate status code) from main to finish the program is the preferred way in C++.
Other option is exit. The point is you can call it anywhere in the code. However, in C++ exit is not recommended that much. Regarding C, there is a question here which discusses whether using exit in C is a good idea or not.
You can use the exit() function to terminate the process at any point during step1(), step2()... anywhere actually.
exit will terminate the program from wherever you are, but in most cases this is a bad idea, checking the return value of a function and handling (e.g. exit in your case) is a cleaner way to do it (no need for globals)

Why should I not use exit function in C? [duplicate]

This question already has answers here:
Should we use exit() in C?
(7 answers)
Closed 7 years ago.
I've been making some school project and I've used this function for error outputs:
void errorMsg(char* msg)
{
fprintf(stderr, msg);
exit(EXIT_FAILURE);
}
So I can do something like this:
if (condition)
errorMsg("Error, Wrong parameters.");
Message will be shown to user and program will exit with error code.
But I've recieved minus points for using exit function.
So I was just wondering how should I do it? Is there some another way than writing this for several times in main function?
if (condition)
{
fprintf(stderr, "Error, Wrong parameters.");
return(EXIT_FAILURE);
}
Thanks for you time.
It really depends on how you program, or in this case, how your teacher wants you to program.
The best answer at this case, is to go to your teacher and ask for an explanation why this is wrong.
When I program in C, all my functions always return int (or a typedef of int) and then I can return errors from functions. Then my main function returns an error as it returns. Something like this template:
int func(void)
{
int return_value = 0;
if (/* Some condition */) {
return_value = 1
}
/* Some code */
return return_value;
}
int main(void)
{
int return_value = 0;
return_value = func();
return return_value
}
Using this template, if there is an error, 1 would be returned from the main function, and in case of success, 0 would be returned. As well, you can add an if condition in the main function, to check the return value of func. This gives you the option to handle errors in your code.
One important reaons:
If you have some code which has opened files, but not yet finished to write in them, and this piece of code delegates some work to a function that will end the program, what happens?
Right, you´ll get a broken file.
Same reasoning is valid for allocated memory, open handles of any kind, etc.etc.
Instead of thinking everytime if the function could end the program, don´t write such functions in the first place. It doesn´t matter if everything is ok or not, but return the "control" after a function to the caller everytime. The only place where exit could be ok is main, because it will basically do the same thing as return there. And in main, there´s no reason to not write return in the first place.
My opinion is that exit functions are harder to test. I struggled a lot while testing a function that has exit call.

Breaking up from while loop in lex

so I have using lex tool in linux and fell into an embarrassing position position , I couldn't break from a while loop.
e.g : I wrote ;
while(1)
{
int x = yylex();
switch(x):
case(ID):printf("ID");
case(NUM):printf("NUM");
}
Now I am reading from a file using yyin ; the problem is that the while loop does not fail after reading the whole file and keeps asking for more inputs at the terminal . Therefore I could not invoke other functions after calling the while loop . I know I am missing something basic , it will be great if somebody can provide an insight into this problem .
P.S# Thanks all for your answers ; tension and lack of sleep before homework submission date ; btw - I figured my answer already .
I see some issues with the C code, independent of what's going on inside the yylex() function. You quote the code as:
while(1)
{
int x = yylex();
switch(x):
case(ID):printf("ID");
case(NUM):printf("NUM");
}
This clearly isn't the source you compiled because it is not acceptable as C. You need to replace the first colon (after switch(x)) with an open brace {, and you need another close brace } at the end, to yield:
while(1)
{
int x = yylex();
switch(x)
{
case(ID):printf("ID");
case(NUM):printf("NUM");
}
}
This is syntactically valid C code, but there are still problems:
There should probably be a break; after each case.
There should probably be a default: clause, which might be used to terminate the loop (but you can't use break to do that inside the scope of a switch).
The printf() statements should print a newline so that the data appears.
Since yylex() returns 0 when it reaches the end, you should probably revise the code so it is more like:
void function(void)
{
int x;
while ((x = yylex()) != 0)
{
switch (x)
{
case ID:
printf("ID\n");
break;
case NUM:
printf("NUM\n");
break;
default:
printf("Other: %d\n", x);
break;
}
}
}
This will at least show you what's going on, and does not have an infinite loop unless you've written your lex analyzer such that it does not terminate properly. I opted not to have the default case terminate the loop since the loop is bounded by yylex() returning 0 instead.
When you write while (1), you are writing an infinite loop. It is incumbent on you to consider whether the loop is really infinite or not. If it is not, then you should aim to be able to make a test at the top of the loop that controls whether there is another cycle to the loop or not.
yylex() returns 0 at the logical end of input. Try this:
int x = -1;
while(!(x == 0))
{
x = yylex();
switch(x):
{
case(0): printf("that's all, folks!"); break;
case(ID): printf("ID"); break;
case(NUM): printf("NUM"); break;
}
}
Well, while I'll admit I'm not familiar with what lex is, I do know quite a bit about the linux environment and the terminal, so...
Try typing 'Ctrl' and 'c' at the same time while in the terminal. If that doesn't work, use 'Ctrl' + 'z'. If you don't mind having the process stopped in the background until the computer turns off and it goes away entirely, after Ctrl + Z you don't need to do anything else. If Ctrl + C worked, then the program's ended and you're fine.
If, for whatever reason, neither work, if you know the name of the program you wrote, you can type into the terminal:
pkill -9 [insert name of program here]
...which will send an unignorable kill signal to the process, and return all its memory (RAM- it won't undo changes made to disk) to the parent process.
If you DON'T know the name of the program, but you think you'll probably be able to recognize it, you can try:
top
which will bring up all the currently running processes in the terminal. Once you locate the name of your still-running program, press q to exit top, and then type in the kill command above with the name you recognized in top. If you don't know the program's name, and Ctrl + Z worked, but you don't want the stopped job to keep hogging its memory until you've turned off the computer, you can type:
ps -a
while in the terminal session from which you ran (and stopped) the program, and the job which shows up labeled 'stopped' is, in all likelihood, yours. Again, using the pkill command above will kill it. If, for whatever reason, you know the process ID but not the name (I don't know why you would, but there you go...), you could use the command 'kill' instead of 'pkill' (instructions for how to use these commands are all over the internet so I won't mention them here. They also have helpful help manual pages which can be accessed via:
man [the name of the program you want help with; 'pkill' or 'kill', in this case.]
To add to David's answer, here's a different version:
do
{
int x = yylex();
if (!x)
break;
switch(x):
{
case(ID): printf("ID"); break;
case(NUM): printf("NUM"); break;
}
} while(1);
This was only to show that you can break out of a while(1). You keep the x in local scope, and you don't evaluate the first pass or switch unnecessarily. Of course someone will most likely pull out the trump card of "it isn't as readable"...

Calling executable file inside C program

I have a C program which will take one argument as input and, if the argument is matching with the string inside the executable, it will return 1 otherwise 0. The executable file name is prg1. I have some input strings in a file named inputs.txt. I want to get those strings from the input file and call the prg1 inside a C program with each string.
I have tried the following code but it's not working.There is no segmentation fault but when i am calling prg1 it executes, Because the printf() statement inside prg1 is working and i can see the output.it changes variable found to 0I cant change the prg1. Because my friend has given the executable file of that program to me, not the source code. Header files are stdio.h and string.h
int main()
{
FILE *fk;
char text[80],inp[16],test[50]={"./prg1 "};
int found=100;
fk=fopen("inputs.txt","r");
while((fscanf(fk,"%s",inp))!=EOF)
{
strcat(test,inp);
found=system(test);
if(found==1)
{
printf("\nAnswer is : %s",inp);
break;
}
strcpy(test,"./prg1 ");
}
fclose(fk);
return 0;
}
What is wrong with my code?
I am not sure of what you want to achieve but here are some comments:
1 - You should test the return value of fopen:
if (!fk) { ... }
2 - You're not cleaning the test buffer between each test, so you are effectively calling:
system("prg1 first_word");
system("prg1 first_wordsecond_word");
...
You should have something like:
strcpy(test, "prg1 ");
after entering the loop and before strcat.
3 - Do you have spaces in your input strings? You should fix your code to read until a newline in this case.
4 - You might want to use EXIT_SUCCESS and EXIT_FAILURE instead of 0 and 1.
prog1 returns 1 when finding match, but 1 stands for error (at least in linux systems). Try returning EXIT_SUCCESS and EXIT_FAILURE (defined in stdlib.h). Then, when the system() call returns 0, the match is found, when anything else, match is not found.
The fundamental flaw in your code is that you need to reset the contents of the 'test' array to be "prg1 " at the beginning of each iteration of the main loop, before you call strcat to add the next argument to the command line. Otherwise the command to be run will just continue to get longer with each iteration, as each input read is added to the existing command. I don't think that is what you intend.
For example, given two lines of input, "foo" and "bar", the first iteration of the loop will cause the command "prg1 foo" to be executed, while the second will cause "prg1 foobar" to be executed. An easy way to have checked that would be to insert a printf (or similar) before the call to system() to display what command is going to be executed.
You also should check the return code of fopen and check array bounds when assigning to an array using fscanf.

Resources