syntax error before ';' token - c

I wrote a quick program (Calculating wages) to help me stay up to speed. For some reason when I compile this I keep getting the error "53: syntax error before ';' token"
#include
int main()
{
#define week 7;
#define year 365;
int jan,feb,mar,apr,may,june,july,aug,sep,oct,nov,dec;
int wage; /* Upgrade to float in future */
char input,month;
int holder;
jan=mar=may=july=aug=oct=dec=31;
apr=june=sep=nov=30;
feb=28;
for(;;)
{
if(input='y')
{
#define YEAR 366;
break;
}
else if(input='n')
{
break;
}
else
{
printf("Unable to understand input");
}
}
printf("Enter wage/day in pounds.\n?\n");
scanf("%d",&wage); /* unsure if I need to get string and then use atoi */
printf("Wage per day:\t%d\n",wage);
printf("Wage per week:\t%d\n",wage*7);
printf("Wage per month:\t%d\n",wage*30);
holder=YEAR;
printf("Wage per year:\t%d\n",wage*holder);
printf("As months have varying day amounts, if you wish to view a specific month type:\n");
printf("A-Jan\nB-Feb\nC-Mar\nD-Apr\nE-May\nF-June\nG-July\nH-Aug\nI-Sep\nJ-Oct\nK-Nov\nL-Dec\nor type X-to EXIT");
month=getchar();
if((month=='A')||(month=='C')||(month=='E')||(month=='G')||(month=='H')||(month=='J')||(month=='L')){
printf("Wage for this month will be:\t%d",wage*31);
}
else if((month=='D')||(month=='F')||(month=='I')||(month=='K')){
printf("Wage for this month will be:\t%d",wage*30);
}
else if((month=='B')&&(year==365)){
printf("Wage for this month will be:\t%d",wage*28);
}
else if((month=='B')&&(year==366)){
printf("Wage for this month will be:\t%d",wage*29);
}
else if(month=='X'){
exit(1);
}
return 0;
}
No matter how many times I read through it I just can't manage to see what I'm doing incorrectly.
As a side note, if anybody feels like screaming/giving pointers about my style go ahead as I appreciate any tips that can lead to the improvement of my skills.
Thanks everyone, that was an overwhelmingly fast response, I've got the code compiled correctly so now I can start debugging the runtime errors (Before anyone mentions it. Yes I do understand the need to flush after input)

One error (though not the one that immediately got you, it seems) is this line:
exit 1;
In C, exit is a regular function, and so you have to call it like this:
exit(1);
As others have pointed out, your use of || is also incorrect, though that is probably giving you warnings (if anything) and not errors.

You cannot do
if (month=='A'||'C'||'E'||'G'||'H'||'J'||'L'){
...
}
This way month=='A'||'C'||'E'||'G'||'H'||'J'||'L' you are comparing the wrong values, i.e. <bool> || <char> || <char> ||..., which gives you an invalid syntax.
Try this instead,
if (month=='A' ||
month=='C' ||
month=='E' ||
month=='G' ||
month=='H' ||
month=='J' ||
month=='L') {
...
}
However, as mentioned by #danfuzz, the issue seems to lie elsewhere...

There are many catastrophic problems with your code, but most of them (besides the exit 1 bit) are formally compilable. They're just not doing what you think they're doing.
However, you state that you get a compilation error well before that exit 1 line. If that is the case, then it must be caused by something you aren't showing us, since there's no ; on line 53. My guess would be that year is defined as a macro that contains ;.
EDIT: In the comments you said that you have defined year as 365. I suspect that you did this
#define year 365;
This is what's causing the error. Get rid of that ; after 365. However, if that's the case I still don't get why you would compare your year to 365 or 366 if you already defined it to be 365 specifically.
EDIT: So, it is exactly as I guessed. You don't need those ; after #define statements for manifest constants. This is your error. Macros are replaced by textual substitution meaning that currently your
if((month=='B')&&(year==365)){
gets translated into
if((month=='B')&&(365;==365)){
which is what causes the original error. If you want to define year as a macro constant that stands for 365, it should be
#define year 365
The same applies to week, although you are not using it anywhere in your code.

Your sintax is wrong, the correct way to write that is:
if((month=='A')||(month=='C')||(month=='E')||(month=='G')||(month=='H')||(month=='J')||(month=='L')){
printf("Wage for this month will be:\t%d",wage*31);
}
and so on. But you may want to consider the switch which is probably more easy to read.
switch( month ) {
case 'A':
case 'C':
case 'E':
case 'G':
case 'H':
printf( "statement A\n");
break;
case 'K':
case 'D':
case 'F':
printf( "statement B\n");
break;
case 'B':
if( year == 365) {
printf( "something else\n" );
} else if( year == 366 ) {
printf( "something else\n" );
} else {
printf( "Unexpected year %d\n", year );
}
break;
case 'X':
return -1; /* Note here return... not exit! */
default:
printf( "Why am I here?\n" );
break;
}
Now that you edited another error is #define YEAR 365;
Get rid of that ';'. You may prefer defining that as int instead of using a precompiler define, expecially if you are going to change its value

Related

Is there any better implementation for this switch case construct?

I'm working on an embedded system where a register hast to be accessed and after that to be incremented to achieve the result I'm looking for, since the machine is notifying and configured to react on my access and changing or not changing the flag. So the switch's argument has to be kept as it is, since it would otherwise change the behaving of the embedded system.
But there may occur a situation where I don't want to get any of the cases get invoked. But I still need to acces and increment the argument of the switch.
(More indepth I'm converting a sequence of analog values to digital values conversions step by step. The index is used to stay synchronized with the current conversion and relating it with the corresponding case to handle the figure correct. There may occur a state in which the index desynchronisizes to the current conversion so the sequence of conversions must be run through without any of the cases getting invoked (to prevent setting wrong data) untill the sequence is finished and the resynchroinisation can get performed)
The way I'm currently doing this is this:
switch (RunIndex++)/*RunIndex may only be accessed one time per execution
of this construct and has to be incremented in the same step. thats given.*/
{
if (RunIndexSyncedWithADCensured == false)
{
break;
}
case 0:
Case0RelatedData = SomeOperationsForCase0(RawData);
break;
case 1:
Case1RelatedData = SomeOperationsForCase1(RawData);
break;
case 2:
Case2RelatedData = SomeOperationsForCase2(RawData);
break;
default:
RunIndex = 0;
break;
}
This construct does the job but it looks like it is a bit controversial and I don't feel well by considering about committing this into productinal code.
So is there a better looking way to achieve the same, without the need of additional variables or assignements?
note:
Also it may be relevant, that this is in the first part of a interupt function consisting of 2 parts.
The first part handles what has to happen if() a conversion is finished. The second part, what has additional to be done if() this conversion also ended the sequence. So it is no option to simply return from the function without getting into the second part. and there is currently no loop structure where an if(...)break; may break out. (What is also the reason why I'm putting the if inside the switch scope, as it is at least by standard a valid way to break out.)
Firstly, the if() inside switch() will never be executed.
Consider the below code snippet:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 2;
switch(i) {
if (i == 2) {
printf("I M HERE\n");
}
case 1:
printf("1\n");
break;
case 2:
printf("2\n");
break;
default:
printf("default\n");
break;
}
return 0;
}
For your code: you expect the string I M HERE to be printed. But that is not the case.
The output for the above code snippet is:
2
No statements before case/default(switch constructs): is executed inside switch
Now to answer for
I don't want to get any of the cases get invoked. But I still need to acces and increment the argument of the switch
Just move the if() outside to the switch().
if (RunIndexSyncedWithADCensured) {
switch (RunIndex++) {
case 0:
Case0RelatedData = SomeOperationsForCase0(RawData);
break;
/* Other cases here */
default:
RunIndex = 0;
break;
}
} else
RunIndex++;
Why not save the value first and then increment it and use the saved value in the switch? By the way this also includes two accesses, first to read the value from RunIndex and the second to increment it.
int runIndex = (RunIndex++);
if (RunIndexSyncedWithADCensured )
{
switch (runIndex)/*RunIndex may only be accessed one time per execution
of this construct and has to be incremented in the same step. thats given.*/
{
case 0:
Case0RelatedData = SomeOperationsForCase0(RawData);
break;
case 1:
Case1RelatedData = SomeOperationsForCase1(RawData);
break;
case 2:
Case2RelatedData = SomeOperationsForCase2(RawData);
break;
default:
RunIndex = 0;
break;
}
}
Since you are using adjacent index numbers, you could make an array of function pointers to replace the switch. That's what the optimizer will turn the switch into anyhow. So instead of your obscure switch, you get this:
if (RunIndexSyncedWithADCensured)
{
SomeOperationsForCase[RunIndex](RawData);
}
RunIndex++;
if (RunIndex > MAX)
{
RunIndex = 0;
}
Completely unrelated to the switch statement design: in case RunIndex is a sensitive volatile variable such as some hardware register, then you shouldn't use it directly in any form of computations. Make a copy of it:
volatile int RunIndex;
...
int index = RunIndex; // read from RunIndex
if (RunIndexSyncedWithADCensured)
{
SomeOperationsForCase[index](RawData);
}
index++;
if (index > MAX)
{
index = 0;
}
RunIndex = index; // write to RunIndex
This is standard practice for all such volatile variables.

Expected declaration or statement at end of input. I counted the correct amount of brackets

I checked the internet before posting this question, and the answer that i found was that i might have missing brackets.
int main (void) {
int input = 0;
while(input != 3) {
printf("Please select an implementation :"
"\n1. Linked list implementation"
"\n2. Ring buffer implementation"
"\n3. Exit");
fflush(stdout);
scanf("%d",&input);
switch(input) {
case 1: printf("Linked List");
break;
case 2: printf("Ring Buffer");
break;
case 3: printf("Goodbye!");
break;
}
}
return 0;
}
I removed all the code inside the cases to make it all shorter, but i still get the error. More specifically :
At the line of int main(void) { I get the error
'main' is normally a non-static function [-Wmain]
At the line of the final } I get the error :
expected declaration or statement at end of input
I tried clean and refresh, building the project again and i also restarted the computer but nothing changed.
Thanks a lot!
Given that your .c file is perfect, I have seen this before, the error must be in one of your header (.h) files.
The reason you are getting that error is that you probably declared main in some other file, whereas the compiler only expects it to exist in your .c file. You may also want to consider using a default case in your switch statement.

Strange switch's behaviour in c

I want the code below to print ok when user enters 1 or 3, or to print why otherwise.
Why, when user enters 3, the program prints why?
#include <stdio.h>
#include <conio.h>
int main(void){
int i;
clrscr();
scanf("%d", &i);
switch(i){
case (1||3):
printf("ok\n");
break;
default:
printf("why\n");
}
getch();
return 0;
}
case(1||3):
Will not work. If you want to say "1 or 3", write:
case 1 :
case 3 :
printf("ok");
break;
If you don't have break between cases, they flow from one into the next. Try it in the debugger.
Expression
1||3
has constant value 1. Operator || is the logical OR operator that according to the C Standard
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
So if you enter 1 then code under the case label will be executed. Otherwise the code under the default label is executed.
In fact your switch statement looks like
switch(i)
{
case 1:
printf("ok");
break;
default:
printf("why");
}
Expression 1 || 3 will be calculated at compilation time and the compiler will generate code that will correspond to the label
case 1:
All case label expressions are evaluated at compilation time and instead of the expressions the compiler uses their results.
To achive the result you want you should either add one more case label or substitute the switch statement for a if-else statement. For example
switch(i)
{
case 1:
case 3:
printf("ok");
break;
default:
printf("why");
}
or
if( i == 1 || i == 3 )
{
printf("ok");
}
else
{
printf("why");
}
You want to learn the following paradigm for flow control:
switch(i)
{
case (1):
case (3):
printf("ok");
break;
default:
printf("why");
}
Where either 1 or 3 will fall through until the break.
1||3 => true... which is typically 0x1
Yet another solution:
printf( (i==1||i==3)?"ok":"why" );

Compiler throwing an error case label does not reduce to a constant

In my homework, I've been asked to write a program using both if and switch statement to compare the net amount paid by a customer for the following details
Purchase Amount (100-200) then give 5% Discount.
Purchase Amount (200-500) then give 7.5% Discount.
Purchase Amount (500-800) then give 10% Discount.
Purchase Amount (Above 1000) then give 15% Discount.
This is something I could come up with, but while compliling it is given me error like
Line 10: error: case label does not reduce to an integer constant
Line 13: error: case label does not reduce to an integer constant
Line 17: error: expected expression before ':' token.
Can anyone please help me with this. Am I not following the question correctly or there is something else I'm doing wrong
#include<stdio.h>
main()
{
int pa = 200;
float net;
printf("\n Enter purchased amount");
scanf("%d",&pa);
switch(pa)
{
case 1&&pa<=100:
net=pa;
break;
case pa>=101&&pa<=200:
net=pa-(5.00/100.00)*pa;
break;
default:
if(pa>=201&&pa<=500)
net=pa-(7.5/100.00)*pa;
if(pa>=501&&pa<=800)
net=pa-(10.00/100.00)*pa;
if(pa>=1000)
net = pa - (15.00/100.00)*pa;
break;
}
printf("\n the net amount to be paid is%f",net);
getch();
}
case label should be compile time constant.
You cannot give a variable inside case label. Expression in label have to be evaluated at compile time.
If you want to branch during run time, use if-else.
if you use switch case, you must match against exact values (constants), otherwise,use cascaded if's
Just read how switch/case work
For range related condition, it'd better to use if/else condition. switch/case is for constant value condition.
if (pa >= 1 && pa <= 100) {
net = pa;
} else if (pa>=101&&pa<=200) {
net=pa-(5.00/100.00)*pa;
} else if (pa>=201&&pa<=500) {
net=pa-(7.5/100.00)*pa;
} else if (pa>=501&&pa<=800) {
net=pa-(10.00/100.00)*pa;
} else if (pa>=1000) {
net = pa - (15.00/100.00)*pa;
} else {`<br/>
/* invalid pa handling */
}

Switch and default: for C

Sorry if this sounds like a very basic question, it is my first time on here!
I am having some difficulties with coding for C, specifically with a switch and the default of that switch. Here is some example code:
#include<stdio.h>
int key;
main()
{
while((key=getchar())!=EOF)
{
printf("you pressed %c \n",key);
switch(key){
case'0':
case'1':
case'2':
case'3':
printf("it's a numeral\n");
break;
default:
printf("it's not a numeral\n");
}
}
}
The actual code is a bunch longer, this is purely an example.
So the code compiles it and I execute it, but I get:
"You pressed 1, it's a numeral, you pressed , it's not a numeral."
My code seems to 'fall through' and repeat itself without referring to either one. If anyone could help that would be great as this is an example in a text book and I am utterly stuck!
Kindest Regards.
You need to account for entering the Enter key, which produces a '\n' on *nix systems. I am not sure what pressing the Enter key does on Windows systems.
Here's your original code doctored up to eat the return key.
#include<stdio.h>
int key = 0;
main()
{
while((key=getchar())!=EOF)
{
if('\n' == key)
{
/* Be silent on linefeeds */
continue;
}
printf("you pressed %c \n",key);
switch(key){
case'0':
case'1':
case'2':
case'3':
printf("it's a numeral\n");
break;
default:
printf("it's not a numeral\n");
}
}
}
You maybe using getchar() for a specific reason, but my experiences in C usually involved reading the whole line, and RTL functions like scanf will eat the line terminator for you.
You need to eat the newline character, that is put in the read buffer when you hit return.
Issue another call to getchar after or before the switch to solve your problem.
Here is an idea...immediately before the printf(), insert logic to ignore spaces and all control characters...
if(key <= ' ')
continue;
printf(...) ...
I dont know if that is the problem, but you have three case without a break. So you press key "1" and there is nothing to do for the programm and so ins go to the next case how is right and this is the default.
Although you take a char in an int-variable???
In your Example it is a better way to take a if-clause like this:
#include<stdio.h>
char key;
main()
{
while((key=getchar())!=EOF)
{
printf("you pressed %c \n",key);
if(key == '0' || key == '1' || key == '2' || key == '3'){
printf("it's a numeral\n");
}
else {
printf("it's not a numeral\n");
}
}
Code is not tested. ;-)
The best way in bigger programms is to work with regular expressions.
I hope, this answer was helpful.
the problem might be due to, input buffer not flushing. when "1" is matched in the switch case, a newline character remains in the buffer.
try this,
fflush(stdin)

Resources