Exersice 1-13 from K&R - c

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".

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

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 )

K&R C Histogram

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.

Character, Line and Word Counter in C [closed]

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;
}

Error: Expected primary-expression before '=='

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'){

Resources