what is the difference between these statement

A

ashu

Dear friends, i am trying to solve one question about word counting
and i am surprise by statement behaviors,
actully i want to check if is a character not a space,tab or newline,
i am not giving full code.


1st statement :
if(c==' '|| c=='\n' || c== '\t') {then go to next character }
else ( increase no of word}

it checks if character is a space,tab or newline and i will do nothing
with it.else i increase no of word. works fine

2nd statement :
if(c!=' '|| c!='\n' || c!='\t')
{ increase no of word}
i want to directly check if not a space,tab or newline but this
statement is doing nothing , why?

example : this is a test
statement 1st works fine returns 2
but statement 2nd does nothing.
 
B

Ben Bacarisse

ashu said:
Dear friends, i am trying to solve one question about word counting
and i am surprise by statement behaviors,
actully i want to check if is a character not a space,tab or newline,
i am not giving full code.


1st statement :
if(c==' '|| c=='\n' || c== '\t') {then go to next character }
else ( increase no of word}

it checks if character is a space,tab or newline and i will do nothing
with it.else i increase no of word. works fine

Maybe the code in your program works, but all I have is what you wrote.
You have two spaces here: c==' ' rather than one and that won't work.
Rule 1 of Usenet: cut and paste, don't re-type!
2nd statement :
if(c!=' '|| c!='\n' || c!='\t')
{ increase no of word}
i want to directly check if not a space,tab or newline but this
statement is doing nothing , why?

The negation of

c == ' ' || c == '\n' || c == '\t'

is

c != ' ' && c != '\n' && c != '\t'

Maybe that is what you meant? Look up "De Morgan's Laws". Of course,
you could have written:

if (!(c == ' ' || c == '\n' || c == '\t')) ...

This is just a guess. In general, full programs are clearer than
fragments.
 
D

Dr Nick

ashu said:
Dear friends, i am trying to solve one question about word counting
and i am surprise by statement behaviors,
actully i want to check if is a character not a space,tab or newline,
i am not giving full code.


1st statement :
if(c==' '|| c=='\n' || c== '\t') {then go to next character }
else ( increase no of word}

it checks if character is a space,tab or newline and i will do nothing
with it.else i increase no of word. works fine

2nd statement :
if(c!=' '|| c!='\n' || c!='\t')
{ increase no of word}
i want to directly check if not a space,tab or newline but this
statement is doing nothing , why?

example : this is a test
statement 1st works fine returns 2
but statement 2nd does nothing.

The second statement should do something - because it should always be
true. Think about it - if c is a space it isn't an newline or a tab,
and if it's a newline it isn't a space or a tab, and if it's an 'x' it
isn't a space, or a newline, or a tab. You need && in there - you need
all the conditions to be true, not just one of them.

There is a useful function (in ctypes.h) for this - called "isspace".
So you can replace your pieces of code with:
#include <ctypes.h>
....
if(isspace((unsigned char)c) {then go to next character }
else ( increase no of word}

and
if(!isspace((unsigned char)c)
{ increase no of word}

The "(unsigned char)" bits are in for technical reasons; they prevent
the isspace function doing something silly if you pass an unusual value
to them (like and end of file, or perhaps certain accented characters
depending on various other things). They make it slightly less elegant,
but it's still tidier and will be familiar to experienced programmers.
 
A

ashu

Maybe the code in your program works, but all I have is what you wrote.
You have two spaces here: c==' ' rather than one and that won't work.
Rule 1 of Usenet: cut and paste, don't re-type!


The negation of

  c == ' ' ||  c == '\n' || c == '\t'

is

  c != ' ' && c != '\n' && c != '\t'

Maybe that is what you meant?  Look up "De Morgan's Laws".  Of course,
you could have written:

  if (!(c == ' ' ||  c == '\n' || c == '\t')) ...

This is just a guess.  In general, full programs are clearer than
fragments.

Thankx ben ,i got your point about negation which is clear.
 
A

ashu

Maybe the code in your program works, but all I have is what you wrote.
You have two spaces here: c==' ' rather than one and that won't work.
Rule 1 of Usenet: cut and paste, don't re-type!


The negation of

  c == ' ' ||  c == '\n' || c == '\t'

is

  c != ' ' && c != '\n' && c != '\t'

Maybe that is what you meant?  Look up "De Morgan's Laws".  Of course,
you could have written:

  if (!(c == ' ' ||  c == '\n' || c == '\t')) ...

This is just a guess.  In general, full programs are clearer than
fragments.
i make this proagram which does the work , except for more than 1
blank,tab or newline.
actually this program is solution for counting words and displaying
histogram.K&R 2nd edition exercise 1-13.i read some other solutions in
internet but they are above my mind.

#include<stdio.h>
#include<conio.h>

main()
{
int i,j,c,arr[100];
for(i=0;i<100;i++)
arr=0;
i=0;

while(( c=getchar())!=EOF){
if(c==' '||c=='\n'||c=='\t'){
++i;
}


else
{
arr=arr+1;
}



}
for(c=0;c<i;++c){

for(j=1;(j<=arr[c])&&(arr[c]!=0);++j)
printf("*");

printf("\n");
}

getch();
}
 
B

Ben Bacarisse

Dr Nick said:
There is a useful function (in ctypes.h) for this - called "isspace".
So you can replace your pieces of code with:
#include <ctypes.h>
...
if(isspace((unsigned char)c) {then go to next character }
else ( increase no of word}

I don't think K&R have introduced these by the time this exercise is
set. No reason not to mention them, of course, but you then have to
explain the (unsigned char)c cast:

The "(unsigned char)" bits are in for technical reasons; they prevent
the isspace function doing something silly if you pass an unusual value
to them (like and end of file, or perhaps certain accented characters
depending on various other things).

The OP has now posted their full code and they correctly have

int c;
...
... c = getchar() ...

so the cast is not needed. In fact, if they changed the code so that
EOF might to be passed to a ctype function, the cast makes the code
wrong! I realise you could not know that c was an int set by getchar()
at the time you posted, but there was always a risk such advice could be
wrong or confusing.

<snip>
 
B

Ben Bacarisse

ashu said:
On May 6, 4:29 pm, Ben Bacarisse <[email protected]> wrote:
<snip everything>

You were not commenting on what I wrote (that's fine)so you
could have cut it out. It makes reading news simpler if messages
contain only what they need to contain.
i make this proagram which does the work , except for more than 1
blank,tab or newline.
actually this program is solution for counting words and displaying
histogram.K&R 2nd edition exercise 1-13.i read some other solutions in
internet but they are above my mind.

I have re-formatted your code. Isn't it much nicer like this? It's
worth paying attention to what your code looks like.
#include <stdio.h>
#include <conio.h>

main()
{
int i, j, c, arr[100];

arr is not a good name for any array. Apart from temporary counters
like i, it's better to use names the describe the data.
for (i = 0; i < 100; i++)
arr = 0;
i = 0;

while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t') {
++i;
}
else {
arr = arr + 1;
}
}


Lets "play computer". The input is:

two lines
of text

so your code does this:

c i arr
i = 0
't' arr[0] = 1
'w' arr[0] = 2
'o' arr[0] = 3
' ' i = 1
'l' arr[1] = 1
'i' arr[1] = 2
'n' arr[1] = 3
'e' arr[1] = 4
's' arr[1] = 5
'\n' i = 2
'o' arr[2] = 1
'f' arr[2] = 2
' ' i = 3
't' arr[3] = 1
'e' arr[3] = 2
'x' arr[3] = 3
't' arr[3] = 4
'\n' i = 4
EOF

So, what has this achieved? It certainly does not look like it's
collecting a histogram of word lengths.

You won't be able to write a program until have a plan. You need to
work out how you would do it if all you could see is the sequence of
characters. Once you've done that, you can translate the plan into C.
for (c = 0; c < i; ++c) {
for (j = 1; (j <= arr[c]) && (arr[c] != 0); ++j)
printf("*");
printf("\n");
}
getch();
}
 
D

Dr Nick

Ben Bacarisse said:
I don't think K&R have introduced these by the time this exercise is
set. No reason not to mention them, of course, but you then have to
explain the (unsigned char)c cast:

At this time I didn't know it was from K&R.
The OP has now posted their full code and they correctly have

int c;
...
... c = getchar() ...

so the cast is not needed. In fact, if they changed the code so that
EOF might to be passed to a ctype function, the cast makes the code
wrong! I realise you could not know that c was an int set by getchar()
at the time you posted, but there was always a risk such advice could be
wrong or confusing.

<snip>

OK. I'll go away now. Sorry for trying to be helpful but not being
telepathic.
 
B

Ben Bacarisse

Dr Nick said:
At this time I didn't know it was from K&R.

No indeed. And as I said, there's no reason not to mention them.
OK. I'll go away now. Sorry for trying to be helpful but not being
telepathic.

I'm sorry if I offended you. Please continue to give advice. The more
voices here the better, in my opinion.
 
D

Dr Nick

Ben Bacarisse said:
No indeed. And as I said, there's no reason not to mention them.


I'm sorry if I offended you. Please continue to give advice. The more
voices here the better, in my opinion.

Thanks. Sorry if I was touchy.

To try to turn this into something constructive. Are there any
circumstances in which casting the argument to a ctype function to
unsigned char would cause problems (apart from doing it before checking
for EOF - like "toupper(getchar())").

I can't think of one.
 
B

Ben Bacarisse

Dr Nick said:
To try to turn this into something constructive. Are there any
circumstances in which casting the argument to a ctype function to
unsigned char would cause problems (apart from doing it before checking
for EOF - like "toupper(getchar())").

I can't think of one.

I can only think of very contrived situations that rely on the
distinction between conversion and re-interpretation on machines with
odd number representations. And in these situations I think a case can
be made that the problem lies elsewhere.

BTW, a plausible "EOF" example would be:

int c;
while (isspace(c = getchar())); /* skip space */
 
D

Dr Nick

Ben Bacarisse said:
I can only think of very contrived situations that rely on the
distinction between conversion and re-interpretation on machines with
odd number representations. And in these situations I think a case can
be made that the problem lies elsewhere.

BTW, a plausible "EOF" example would be:

int c;
while (isspace(c = getchar())); /* skip space */

Even in that case,
while (isspace((unsigned char)(c = getchar()))); /* skip space */
isn't going to do any harm. 'c' still holds the uncast EOF and can be
tested for later.

Except in a pathological case where EOF cast to unsigned char turns into
a space character I suppose - could that actually happen?
 
J

James Kuyper

On 05/09/2012 01:54 AM, Dr Nick wrote:
....
Even in that case,
while (isspace((unsigned char)(c = getchar()))); /* skip space */
isn't going to do any harm. 'c' still holds the uncast EOF and can be
tested for later.

Except in a pathological case where EOF cast to unsigned char turns into
a space character I suppose - could that actually happen?

If UCHAR_MAX > INT_MAX, there has to be some valid unsigned char value
that, when written to a file, and read back by getchar(), results in it
returning EOF. There's no inherent reason why it couldn't be a space
character, though that is rather unlikely.
 
B

Ben Bacarisse

Dr Nick said:
Even in that case,
while (isspace((unsigned char)(c = getchar()))); /* skip space */
isn't going to do any harm. 'c' still holds the uncast EOF and can be
tested for later.

Except in a pathological case where EOF cast to unsigned char turns into
a space character I suppose - could that actually happen?

I don't know, and you seem unsure. (BTW, isspace was just an example --
the code could have used isalnum, isprint, isdigit... whatever). Why
give the reader this conundrum when the simpler code is more obviously
correct?

If you already have a value of the right type for a function, a cast
will, at the very least, puzzle some readers. If you reserve the use of
isXXXX((unsigned char)c) to those cases where you don't have an int or
and unsigned char, at least the puzzlement (if there is any) will be
productive.
 
T

Tim Rentsch

Dr Nick said:
Even in that case,
while (isspace((unsigned char)(c = getchar()))); /* skip space */
isn't going to do any harm. 'c' still holds the uncast EOF and can be
tested for later.

Except in a pathological case where EOF cast to unsigned char turns into
a space character I suppose - could that actually happen?

Certainly the Standard doesn't exclude the possibility.

On most implementations, a definition for EOF such as

#define EOF (' ' - (__UCHAR_MAX+1))

(where __UCHAR_MAX has the same value as UCHAR_MAX, but doesn't
need <limits.h>) will result in a valid value for EOF that will
have the same value as space when converted to 'unsigned char'.
A similar construction could produce the same value as that of
any other character desired (on most implementations, ie, those
where unsigned char promotes to int rather than unsigned int, and
the range of int is large enough so overflow does not occur).
 
J

Joe keane

Except in a pathological case where EOF cast to unsigned char turns into
a space character I suppose - could that actually happen?

Why not? There are codes where blank is zero. One can easily imagine
0x100 for a value of EOF (especially 8-bit machines). Even if there is
null and space, do we know that 'isspace' is false for null?
 
K

Keith Thompson

Why not? There are codes where blank is zero. One can easily imagine
0x100 for a value of EOF (especially 8-bit machines). Even if there is
null and space, do we know that 'isspace' is false for null?

C can't use an encoding where ' ' == '\0'; the null character has to be
distinct from any other character value.

(The only such encoding I'm aware of is the one for Knuth's MIX
processor; I'm sure there have been others, but presumably they're all
obsolete.)

The GSM 7-bit and 8-bit character encodings
<http://en.wikipedia.org/wiki/GSM_03.38> use 0x00 for '@'; '@' isn't
part of C's basic character set, but still I presume that software that
deals with it can't use C's string functions to process it.
 
T

Tim Rentsch

Why not? There are codes where blank is zero. One can easily imagine
0x100 for a value of EOF (especially 8-bit machines).

The C Standard doesn't admit either of these possibilities.
Even if there is null and space, do we know that 'isspace' is false
for null?

Yes. More precisely, a qualfied yes in one case, and an
unqualified yes in another. For locales in general, each
implementation is required to document which characters besides
the standard white-space characters will result in isspace()
returning true; so that can be checked. For the C locale in
particular, isspace() must return true only for the standard
white-space characters, and null is not in that set.
 
J

Joe keane

The C Standard doesn't admit either of these possibilities.

I'm a bit confused about why 'EOF' can't be 0x100.

I know it can't be any value of 'unsigned char' converted to 'int', that
is a valid character at least.
 
K

Kaz Kylheku

I'm a bit confused about why 'EOF' can't be 0x100.

Because EOF must be a negative constant of type int.

This is spelled out in 7.19.1 in the 1999 standard where EOF is defined.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top