Error: Expected primary-expression before '==' - c

I'm trying to work through a book on C and I am stuck on the following error:
while((c = getchar()) != EOF){
if(c >= '0' && c <= '9'){
++ndigit[c-'0'];
}
else if (c == ' ' || c == '\n' || == c =='\t'){
++nwhite;
}
else{
++nother;
}
}
The compiler is complaining about my comparison of var 'c' and the whitespace chars.
error: expected primary-expression before '==' token
I haven't written C since school so I am confused as to what is wrong with my syntax. Thanks.

else if (c == ' ' || c == '\n' || == c =='\t'){
^^
|
+-- This == should be deleted.

You wrote:
else if (c == ' ' || c == '\n' || == c =='\t')
But it should be
else if (c == ' ' || c == '\n' || c =='\t'){
Notice the == before the last part of the conditional that is removed, in the second snippet. Even if you haven't written C in a while, it looks like that was a simple typo rather than a misunderstanding of those operators.

Get rid of the == c on the else if line:
else if (c == ' ' || c == '\n' || == c =='\t'){

Well, that == in
if (c == ' ' || c == '\n' || == c =='\t')
^^ Here
makes no sense whatsoever. Why did you put it in there?

this is your problem " == c =='\t')" get rid of the == to the left of the c variable

The problem is on the line else if (c == ' ' || c == '\n' || == c =='\t'){
It's that == c == '\t' at the end that's throwing it off. C doesn't allow you to string together comparisons and, additionally, there's nothing to the left of the == (that's what it means by "expected primary expression before ==", it wants something to compare to but there's nothing).
It should be else if (c == ' ' || c == '\n' || c =='\t'){

Related

Substituting the next character from a stream of characters in a while loop

I'm supposed to design a program that count the number of words, so this is part of my code
while ((c=getc(file)) != EOF)
{ if ((isspace(c) || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')) { ++word; } }
The logic of my code should first look at the first character if it was non-space, then it should look at the following if it was space then it should count one word
However, I know how to substitute the current character (in my code) but I don't know how to substitute the following character?
Basically, I want to write my code in this logic form (c+ is the character that follows c)
while ((c=getc(file)) != EOF)
{ if ( c is non-space)
{ if (c+ is space)
{ word++ }
}
}
prevC = ' ';
while ((c=getc(file)) != EOF)
{
if ((prevC != ' ') &&
(isspace(c) || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'))
{
++word;
}
prevC = c;
}
You need to maintain previous character that was read and compare it in the next iteration

CS50 Pset6 error 405 keeps on printing server.c

So my code, no matter what, returns error 405 (once the test that only two spaces are in the request-line is passed). Which makes me believe I have made an error in creating a code to determine that "GET" is in fact the first word. This is all my code leading up to the "check" that the method type is "GET" or any capitalization thereof.
int s;
s=0;
int i=0;
for(int q=0; q<strlen(line); q++)
{
if(line[q] == ' ')
s++;
}
if(s!=2)
{
error(400);
return false;
}
if((line[i] != 'g' || line[i] != 'G') || (line[i+1] != 'e' || line[i+1] != 'E') || (line[i+2] != 't' || line[i+2] != 'T')||
(line[i+3] != ' ' ))
{
error(405);
return false;
}
Any reason this would always return false? I have int i initialized to 0.
Any reason this would always return false?
Reason :
consider the if statement as :
if(expression_1 || expression_2 || expression_3 || expression_4)
//where
//expression_1 is (line[i] != 'g' || line[i] != 'G')
//expression_2 is (line[i] != 'e' || line[i] != 'E')
//expression_3 is (line[i] != 't' || line[i] != 'T')
//expression_4 is (line[i] != ' ')
let's consider line as GET
Now, expression_1 is always evaluated to be true even though line[i] == G because line[i] != 'g' is true. Therefore, (line[i] != 'g' || line[i] != 'G') is true as true || false == true
Now further expressions are not evaluated as || is a lazy operator and it stops evaluation on first true occurrence as true || anything == true
Thus, if block is always entered and false is always returned.
Solution :
Change the if in your code :
if((line[i] != 'g' || line[i] != 'G') || (line[i+1] != 'e' || line[i+1] != 'E') || (line[i+2] != 't' || line[i+2] != 'T') || (line[i+3] != ' ' ))
To the following :
if((line[i] != 'g' && line[i] != 'G') || (line[i+1] != 'e' && line[i+1] != 'E') || (line[i+2] != 't' && line[i+2] != 'T') || (line[i+3] != ' ' ))
Here line[i] != 'g' && line[i] != 'G' gets evaluated to false as true && false == false and further expressions are checked till a true is encountered.
If no true is encountered then if() block is not entered
Further,
As #twalberg has suggested in the comment, it'd be much readable and understandable if you use your if statement as if( !strncasecmp(line, "get ", 3) ) by including the strings.h header file
Know more about strncasemp() function here : click
That comparison makes the code much harder to read. Use the function strncasecmp() (in either string.h or strings.h) instead:
if (strncasecmp(line, "get ", strlen("get ")) != 0) {
// ...
}
This will fix the logic error in that line -- your current comparison will always evaluate true. I would also suggest enabling more compiler warnings, as this is something that any compiler should catch.

Parsing a text file - any reason why space / new line would be ignored?

I have this while loop...
char count[3] = {0};
int i = 0;
while( c != ' ' || c != '\n' || c != '\t' ) {
count[i] = c;
c = fgetc(fp);
i++;
}
And even though I see while debugging that space and newline are the right ASCII numbers, the while loop does not exit. Anyone know what could be causing this?
The logic in the conditional is not right. It will evaluate to true all the time.
while( c != ' ' || c != '\n' || c != '\t' )
If c is equal to ' ' it is not equal to '\n' or '\t'.
What you probably need is:
while( c != ' ' && c != '\n' && c != '\t' )
And for good measure, I would also add c != EOF.
while( c != ' ' && c != '\n' && c != '\t' && c != EOF )
It might be simpler to use:
while( !isspace(c) && c != EOF )

C - Can't figure out this error : "C2106: '=' : left operand must be l-value"

I am using Visual Studio 2013 to try and learn C language.
I'm using the famous K&R book and after literally copying and pasting the following piece of code from the book to Visual Studio 2013 i got the error :
1 error C2106: '=' : left operand must be l-value
2 IntelliSense: expression must be a modifiable lvalue
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* count lines, words, and characters in input */
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n')
++nl;
if (c == ' ' || c == '\n' || c = '\t')
state = OUT;
else if (state == OUT)
state = IN;
++nw;
}
printf("%d %d %d\n", nl, nw, nc);
}
it seems the error comes from the statement :
if (c == ' ' || c == '\n' || c = '\t')
But i really can't figure what's wrong, not mentioning the fact that the code is straight from the book.
Any help would be greatly appreciated !
Thanks !
if (c == ' ' || c == '\n' || c = '\t')
// ^ Oops.
I suggest you take a break. Even without knowing that the assignment would try to write to the result of || because it has lower precedence, the discrepancy is screaming.
Change c = '\t' to c == '\t' in if's condition. Otherwise the conditional expression will be parsed as
if ( ((c == ' ' || c == '\n') || c) = '\t')
((c == ' ' || c == '\n') || c) is a rvalue (Boolean value; a constant) and it is not assignable (its like 1 = 2).
You need to change the existing
c = '\t'
to
c == '\t'
Otherwise, because of the higher precedence of || than =, your code will behave like
if ( (c == ' ' || c == '\n' || c ) = '\t')
now, as we know, the result of a logical OR operation [int 1 or int 0] is not a modifiable lvaue, you'll see the error.
Just for reference, from chapter 6.5.14, paragraph 3, C99 standard,
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
So, a 1 = '\t' or 0 = '\t' is the reason for the error.
No one explained the reason why you get that error.
Focus on this part of the expression - c == ' ' || c == '\n' || c. Suppose it evaluated to some value say 1 (just a random example). Then you cannot store '\t' in 1 like this 1 = '\t'.
This will evaluate to an expression which is an rvalue and you cannot store '\t' in it.
However this is perfectly legal, even though your code might not work as you expected:
if (c = '\t' || c == ' ' || c == '\n')
note^

Exersice 1-13 from K&R

I am doing the K&R book.
If i check a == then everything works but if I check !=, then no histogram is printed.
This works
while( (c = getchar()) != EOF )
{
if(c == ' ' || c == '\t' || c =='\n')
{
state = OUT;
if(wc>0)
++numOfWords[wc];
wc = 0;
}
else
if(state == OUT)
state = IN;
if(state = IN)
++wc;
}
but changing the if section to this does not:
if(c != ' ' || c != '\t' || c !='\n'){
if(state == OUT){
state = IN;
++wc;}
else
++wc;
}
else
{
state = OUT;
if(wc>0)
++numOfWords[wc];
wc = 0;
}
}
I want every character that is not a tab or a space or a newline. So i wrote c != '\t' || c!= ' ' || c!= '\n'. which i take to mean as
If c is not (!=) space(' ') then its 1(true) OR(||) if c is not (!=) tab('\t') then its 1 OR(||) ...so on.
And if any one of the OR statement is true then the whole statement is true and body should execute, so why isn't it executing?
Thanks for noticing the typo in first snippet, I corrected it, but I want to ask is why doesn't the second snippet work?
Answer:
This works perfectly:
if(c != ' ' && c != '\t' && c !='\n' && c != '"' && c!= '.' && c != ','){
if(state == OUT){
state = IN;
++wc;}
else
++wc;
}
else
{
state = OUT;
if(wc>0)
++numOfWords[wc];
wc = 0;
}
In the first snippet
if(state = OUT)
...
if(state = IN)
is wrong. Change this to
if(state == OUT)
...
if(state = IN)
After that if your first snippet of code works well then change
if(c != ' ' || c != '\t' || c !='\n')
in your second snippet to
if(c != ' ' && c != '\t' && c !='\n')
if you with to negate the whole if stament try if(!(c == ' ' || c == '\t' || c =='\n')) or its logical equivalent if( c != ' ' && c != '\t' && c == '\n')). Negating the individuals elements is not enough. You have to change the or's to and's.
Every character is either "not a space", "not a tab", or "not a newline". A tab, for instance, is "not a space" and "not a newline". So that if-condition will never be false. It sounds like you want to look for characters which are "not a space" AND "not a tab" AND "not a newline".

Resources