This code is taken from C Programming by K & R. I am newbie to C programming and i need little help in understanding this code. This code gives me error please help me how to fix it
#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);
}
Error :
E:\Files\C\main.c:5:1: warning: return type defaults to 'int' [-Wreturn-type]
E:\Files\C\main.c: In function 'main':
E:\Files\C\main.c:14:40: error: lvalue required as left operand of assignment
E:\Files\C\main.c:21:1: warning: control reaches end of non-void function [-Wreturn-type]
You are assigning the value for c instead of comparing.
if (c == ' ' || c == '\n' || c = '\t') state = OUT;
should be
if (c == ' ' || c == '\n' || c == '\t') state = OUT;
And your main function should be like int main(void) and put a return 0 at the end
you are assigning value rather than comparing it:if (c == ' ' || c == '\n' || c = '\t'), == is used for comparison and = is used for assignment.
first of all change main function to int main() at line 5.
Also at line 13 try to use == for making it equal in the way shown below.
if (c == ' ' || c == '\n' || c == '\t') state = out;
//you assign a value instead
Also to terminate a program, at the end write return 0;
Related
Going through Kernighan, and I am coding on visual studio with windows. Why doesn't the following program doesn't pick up tab characters, new lines, or spaces? I have to manually type its associated integer. Here's the word count program:
#define IN 1 /*State of being inside word*/
#define OUT 0 /*State of being outside word*/
countWords() {
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);
}
}
My test input was 'one two three' and the output was '0 1 14'. Indicating that it didn't recognise space character ' '. Is there a setting on VS that needs to be changed to get this working?
Be careful with operator precedence.
while ((c = getchar() != EOF)) {
The c variable gets the boolean value of the expression getchar() != EOF. It doesn't hold the character that was read in like you are probably expecting.
You probably meant to write it as:
while ((c = getchar()) != EOF) {
I am learning the 1.5.4 Word Counting chapter 1 of "C Programming Language, 2nd Edition"
#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);
}
I intimate the codes line by line, but it report error when I tried to compile it,
$ cc word_counting.c
word_counting.c:7:1: warning: type specifier missing, defaults to 'int'
[-Wimplicit-int]
main()
^
word_counting.c:15:16: warning: result of comparison against a string literal is
unspecified (use strncmp instead) [-Wstring-compare]
if ( c == "\n")
^ ~~~~
word_counting.c:15:16: warning: comparison between pointer and integer
('int' and 'char *')
if ( c == "\n")
I double-checked my codes, there's not difference with the original codes.
c is a character. '\n' is a character. "\n" is a string.
You can't compare character and string.
Correct code is
if ( c == '\n')
++nl;
I'm currently doing exercise 1-13 in K&R's C the Programming Language 2nd edition. I decided to start with a simple histogram that just replaces each letter in a word with '*'.
#include <stdio.h>
// histogram
#define IN 1
#define OUT 0
main() {
int c, state;
state = OUT;
while ((c = getchar()) != EOF) {
if (c == '\n' || c == '\t' || c == ' ') {
state = OUT;
putchar('\n');
}
else {
if (c != '\n' || c != ' ' || c != '\t') {
state = IN;
putchar('*');
}
}
}
}
However, take a look at this snippet of code:
else {
if (c != '\n' || c != ' ' || c != '\t') {
state = IN;
putchar('*');
}
}
How come this works, but if I enter if (state != OUT) , it doesn't work? I end up getting a completely different output. Aren't those two statements essentially the same thing?
c being equal to three terms "or" each other is not equivalent c not being equal to the negations of the same three terms "or" each other.
See De Morgan's laws.
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^
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am sorry to ask so many questions but I am clueless what to do when my Program gives me errors which I don't understand how to fix. I use Code Blocks. The book name is The C Programming Language 2nd Edition.
The Code:
#include <stdio.h>
#include <stdlib.h>
#define IN 1
#define OUT 0
int main()
{
int c, nl, nw, nc, state;
state = OUT;
while((c = getchar()) != EOF)
{
++nc;
if (c == '\n')
if (c == '' || c == '\n' || c = '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d \n", nl, nw, nc);
}
So when I build it it gives me error on line 14 saying:
||=== Build: Debug in Line Counter v2 (compiler: GNU GCC Compiler) ===|
C:\Users\Uddhava\Desktop\Uddhava\Learning\Programming\C C+\Line Counter v2\
main.c|14|error: empty character constant|
C:\Users\Uddhava\Desktop\Uddhava\Learning\Programming\C C+\Line Counter v2\
main.c|14|error: lvalue required as left operand of assignment|
||=== Build failed: 2 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
if (c == '' || c == '\n' || c = '\t')
The first thing wrong with this line is that it should be:
if (c == ' ' || c == '\n' || c == '\t')
if (c == '' || c == '\n' || c = '\t')
should be
if (c == ' ' || c == '\n' || c == '\t')
if (c == '\n')
if (c == '' || c == '\n' || c = '\t')
In your code, the first if statement makes the second meaningless.
You are testing the value of c against an empty character constant '', which is not allowed. I think you want to test it against a space ' '.
If you want to test the value of your variable c with an empty space, you should compare it with ' ' instead of ''. Furthermore, comparison operator is ==, not = (assignment), which you used to compare the tab character '\t' in the last condition of your if statement, thus your if statement should be:
if (c == ' ' || c == '\n' || c == '\t')
this code block:
while((c = getchar()) != EOF)
{
++nc;
if (c == '\n')
if (c == '' || c == '\n' || c = '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
does not indicate (via the indentation) exactly which 'if' clause
is related to the 'else clause.
this is a VERY good reason to include ALL the '{' and '}' braces
this is what is actually written in the code:
while((c = getchar()) != EOF)
{
++nc;
if (c == '\n')
{
if (c == '' || c == '\n' || c = '\t') // two errors on this line
{
state = OUT;
}
else if (state == OUT)
{
state = IN;
++nw;
}
}
}
the question becomes: is this what you really wanted?
we already know that the code is not correct
because the second 'if' will ALWAYS fail due to 'c' being
already confirmed as containing a '\n'
and the comparison of 'c' to ''
and the assignment of '\t' to 'c'
therefore, I suspect it should be:
while((c = getchar()) != EOF)
{
++nc;
if (('\n' == c) || (' ' == c) || ('\n' == c) || ('\t' == c) )
{
state = OUT;
}
else if (state == OUT)
{
state = IN;
++nw;
}
}
which would have also caught the assignment of '\t' to c at compile time
rather than you having to spend many an hour debugging the code.
I.E. put the literal on the left side of the comparison operator '=='
Well this worked, I used ideas from Amadeus, user3629249 and Min Fu. Thanks everyone for your help.
Working Code:
#include <stdio.h>
#include <stdlib.h>
#define IN 1
#define OUT 0
int main()
{
int c, nl, nw, nc, state;
state = OUT;
nc = 0;
nl = 0;
nw = 0;
while((c = getchar()) != EOF)
{
++nc;
if (('\n' == c) || (' ' == c) || ('\n' == c) || ('\t' == c) )
{
state = OUT;
++nl;
}
else if (state == OUT)
{
state = IN;
++nw;
}
}
printf("%d %d %d \n", nl, nw, nc);
return 0;
}