468,457 Members | 1,621 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,457 developers. It's quick & easy.

Histogram of character frequencies

Hello everyone,

Thanks again for all the suggestions, though I think some people are a
bit fussy in their answers.

Here is a solution to Exercise 1.14. It deals well with control
characters too.

// make histogram of character frequencies

int x[256]; // frequencies

void main()
{
char c;
int i, y=0, z;
while(! feof(stdin) )
if(++x[c=getchar()]>y)
y=x[z=c];
do {
for(i=0; i<256; i++)
if(x[i]>0)
printf("%s", x[i]>y ? " * " : " ");
printf("\n");
} while(y--);
for(i=0; i<256; i++)
if(x[i]>0)
if(i>32)
printf(" %c ", i);
else
printf("%02x ", i);
printf("\n");
}
Dec 1 '07 #1
35 3921
ra****@thisisnotmyrealemail.com schrieb:
int x[256]; // frequencies
Global.
void main()
Illegal.

Either you are pretty dumb or you actually do not read ANY of the
answers which are given to you. I vote for number one.

Greetings anyways,
Johannes

--
"Viele der Theorien der Mathematiker sind falsch und klar
Gotteslästerlich. Ich vermute, dass diese falschen Theorien genau
deshalb so geliebt werden." -- Prophet und Visionär Hans Joss aka
HJP in de.sci.mathematik <47**********************@news.sunrise.ch>
Dec 1 '07 #2
ra****@thisisnotmyrealemail.com wrote:
Hello everyone,

Thanks again for all the suggestions, though I think some people are a
bit fussy in their answers.

Here is a solution to Exercise 1.14. It deals well with control
characters too.

// make histogram of character frequencies

int x[256]; // frequencies

void main()
You have been told multiple times already that the above is most likely
unportable and pretty bad form.
{
char c;
int i, y=0, z;
while(! feof(stdin) )
You have told multiple times that you test for end-of-file or error
*after* an I/O operation has returned EOF or someother error status.
if(++x[c=getchar()]>y)
getchar() is undefined since you have failed to include the relevant
header (stdio.h). Even if you had done so the above call is still wrong
since getchar() returns an int so that it can return the out of band
value EOF upon end-of-file or error. The character with value zero is a
null character, which you do not normally encounter on interactive
input. You should assign the return value of getchar() to an int object
and test it against EOF before proceeding.
y=x[z=c];
You seem to prefer obfuscation and incorrect code.
do {
for(i=0; i<256; i++)
if(x[i]>0)
printf("%s", x[i]>y ? " * " : " ");
printf("\n");
} while(y--);
for(i=0; i<256; i++)
if(x[i]>0)
if(i>32)
printf(" %c ", i);
else
printf("%02x ", i);
printf("\n");
}
As the other respondent notes you either do not bother to take not of
helpful advice or you are a troll. Unless you show some willingness to
learn from your mistakes you are going to find yourself quickly ignored
by most the group's participants.

Dec 1 '07 #3
ra****@thisisnotmyrealemail.com wrote:
Hello everyone,

Thanks again for all the suggestions, though I think some people are a
bit fussy in their answers.
You need to redefine "fussy". Your code is broken from the very
beginning. Not including header files or otherwise providing required
declarations of variadic functions (printf), and misusing feof() as the
control condition for your loop is bad enough, but the illiterate
void main()
is a sure way to signal your incompetence to anyone reading your code
(and possibly to the compiler as well).

You have been told about these things and refuse to fix them. This
smacks of an obstinacy in error and inability to learn that suggests you
take up Business Administration or some other brainless pursuit instead
of programming.
Dec 1 '07 #4
ra****@thisisnotmyrealemail.com wrote:
void main()
I've decided that you're trolling. Or stupid. Either way, a waste of my
time.

*plonk*


Brian
Dec 1 '07 #5
Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:
int x[256]; // frequencies

Global.
It's completely acceptable to have variables defined at file scope in
C!
>
void main()

Illegal.
Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.
>
Either you are pretty dumb or you actually do not read ANY of the
answers which are given to you. I vote for number one.
I read the answers but mostly people only comment on trivial things
that aren't even errors! I'll be glad to have substantial comments on
my code.
>
Greetings anyways,
Johannes
Greets.
>
--
"Viele der Theorien der Mathematiker sind falsch und klar
Gotteslsterlich. Ich vermute, dass diese falschen Theorien genau
deshalb so geliebt werden." -- Prophet und Visionr Hans Joss aka
HJP in de.sci.mathematik <47**********************@news.sunrise.ch>
Dec 1 '07 #6
On Dec 1, 2:02 pm, raj...@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
raj...@thisisnotmyrealemail.com schrieb:
int x[256]; // frequencies
Global.

It's completely acceptable to have variables defined at file scope in
C!
void main()
Illegal.

Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.
Either you are pretty dumb or you actually do not read ANY of the
answers which are given to you. I vote for number one.

I read the answers but mostly people only comment on trivial things
that aren't even errors! I'll be glad to have substantial comments on
my code.
Greetings anyways,
Johannes

Greets.
--
"Viele der Theorien der Mathematiker sind falsch und klar
Gotteslsterlich. Ich vermute, dass diese falschen Theorien genau
deshalb so geliebt werden." -- Prophet und Visionr Hans Joss aka
HJP in de.sci.mathematik <4740ad67$0$3811$54022...@news.sunrise.ch>

Your program won't even compile on my machine.

[cd*****@eecs.berkeley.edu ~]$ more freq.c
int x[256]; // frequencies

void main()
{
char c;
int i, y=0, z;
while(! feof(stdin) )
if(++x[c=getchar()]>y)
y=x[z=c];
do {
for(i=0; i<256; i++)
if(x[i]>0)
printf("%s", x[i]>y ? " * " : " ");
printf("\n");
} while(y--);
for(i=0; i<256; i++)
if(x[i]>0)
if(i>32)
printf(" %c ", i);
else
printf("%02x ", i);
printf("\n");

}
[cd*****@eecs.berkeley.edu ~]$ gcc --version
gcc (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

[cd*****@eecs.berkeley.edu ~]$ gcc -g freq.c -o freq
freq.c: In function 'main':
freq.c:7: error: 'stdin' undeclared (first use in this function)
freq.c:7: error: (Each undeclared identifier is reported only once
freq.c:7: error: for each function it appears in.)
freq.c:13: warning: incompatible implicit declaration of built-in
function 'printf'
freq.c:19: warning: incompatible implicit declaration of built-in
function 'printf'
freq.c:4: warning: return type of 'main' is not 'int'
[cd*****@eecs.berkeley.edu ~]$
Dec 1 '07 #7
ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
>ra****@thisisnotmyrealemail.com schrieb:
>>int x[256]; // frequencies
Global.

It's completely acceptable to have variables defined at file scope in
C!
What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they aren't
necessary in this case.
Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.
That doesn't make it legal. A conforming implementation of C is allowed
to reject a program which declares main() that way.

....
I read the answers but mostly people only comment on trivial things
that aren't even errors! I'll be glad to have substantial comments on
my code.
Several of the "trivial" things people have commented on ARE errors, and
serious ones - you don't seem to understand how serious. Most
importantly, #inclusion of the appropriate standard headers is
absolutely essential for your code to even compile, at least under most
implentations of C. If what you've given us is the complete text of your
program, and if you are using a compiler which accepts your code as
written, junk it - it's teaching you some very bad habits.

Also, you're using feof() incorrectly, and until you understand why the
way that you're using it is incorrect, I would not recommend relying
upon any of your programs to function properly.
Dec 2 '07 #8
ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
>ra****@thisisnotmyrealemail.com schrieb:
.... snip ...
>>
>>void main()

Illegal.

Why does everyone have this hangup about this? I took a class in C
a while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.
Because they are gross errors, and not allowed in portable code by
the ISO C standard. Which, in turn, is the basis for all code
discussed in this newsgroup. If you want to discuss Microsoft
software (junk), use a Microsoft newsgroup. If you want to discuss
Borland software, use a Borland newsgroup. However, if you want to
discuss C, come here.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Dec 2 '07 #9
ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
>ra****@thisisnotmyrealemail.com schrieb:
==============================================
----->>***READ THE C FAQ*** NOW!!! <<<<-----
......>>***READ THE C FAQ*** NOW!!! <<<<.....
......>>***READ THE C FAQ*** NOW!!! <<<<.....
----->>***READ THE C FAQ*** NOW!!! <<<<-----
==============================================
>>int x[256]; // frequencies
Global.

It's completely acceptable to have variables defined at file scope in
C!
I once asked a COBOL programmer how to create local variable in that
language, the answer I got was:

"What is a local variable?"

;-)
>>void main()
Illegal.

Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.
LOL, yet another "void main" fan boy to be eaten in c.l.c!

FYI, you haven't written a valid C program yet, and your teacher hasn't
told you about *Standard C*, which is the topic here.

==============================================
----->>***READ THE C FAQ*** NOW!!! <<<<-----
......>>***READ THE C FAQ*** NOW!!! <<<<.....
......>>***READ THE C FAQ*** NOW!!! <<<<.....
----->>***READ THE C FAQ*** NOW!!! <<<<-----
==============================================
--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Dec 2 '07 #10
Johannes Bauer wrote:
>
.... snip ...
>
You code contains errors. Why do you post it here? To learn
something? Then accept the hints you're given. You'll be grateful
at some point in time, although you're currently obviously far
too stubborn to realize what you're doing.

If you need somebody to pet you and tells you your code is great,
this is probably the wrong place.
He could try alt.applause.crud.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.

--
Posted via a free Usenet account from http://www.teranews.com

Dec 2 '07 #11
James Kuyper wrote:
ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:

int x[256]; // frequencies
Global.
It's completely acceptable to have variables defined at file scope in
C!

What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they aren't
necessary in this case.
In this case they help simplify the code - the array gets initialized
to 0 at compile-time, instead of needing extra code for an
initialization loop bad for efficiency!
>
Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.

That doesn't make it legal. A conforming implementation of C is allowed
to reject a program which declares main() that way.
But no "conforming implementation" on Windows rejects it! I don't
believe any C compiler anywhere would reject it.
>
...
I read the answers but mostly people only comment on trivial things
that aren't even errors! I'll be glad to have substantial comments on
my code.

Several of the "trivial" things people have commented on ARE errors, and
serious ones - you don't seem to understand how serious. Most
importantly, #inclusion of the appropriate standard headers is
absolutely essential for your code to even compile, at least under most
implentations of C. If what you've given us is the complete text of your
program, and if you are using a compiler which accepts your code as
written, junk it - it's teaching you some very bad habits.
OK you're right I should remember that. However I don't think it's the
end of the world - the standard library is always linked in so the
right functions will be found in the end by the linker.
>
Also, you're using feof() incorrectly, and until you understand why the
way that you're using it is incorrect, I would not recommend relying
upon any of your programs to function properly.
I don't really understand the problem with feof - it just checks if
the EOF indicator is set in a given FILE * struct. Anyway I'll read
about it.
Dec 2 '07 #12
santosh wrote:
ra****@thisisnotmyrealemail.com wrote:
>James Kuyper wrote:
>>ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
....
>>>Why does everyone have this hangup about this? I took a class in C
a while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and
BorLand.
That doesn't make it legal. A conforming implementation of C is
allowed to reject a program which declares main() that way.
But no "conforming implementation" on Windows rejects it! I don't
believe any C compiler anywhere would reject it.

Did you see the post by "Chad" were his conforming compiler refused to
compile your code?
To be fair, the fact that main() was declared as void was not the reason
why Chad's compiler refused the code. Chad was using gcc, and my copy of
gcc accepts void main, unless I choose an option like -pedantic-errors.
Dec 2 '07 #13
ra****@thisisnotmyrealemail.com wrote:
James Kuyper wrote:
>ra****@thisisnotmyrealemail.com wrote:
>>Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:

int x[256]; // frequencies
Global.
It's completely acceptable to have variables defined at file scope in
C!
What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they aren't
necessary in this case.

In this case they help simplify the code - the array gets initialized
to 0 at compile-time, instead of needing extra code for an
initialization loop bad for efficiency!
You can zero initialize automatic variables, too:

int x[256] = {0};

The speed difference between initialization during program startup vs.
after program startup isn't normally large enough to justify worrying
about. The difference in the maintainability of a program that uses
global variables and one that keeps variable as local as possible is far
more important.
>>Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.
That doesn't make it legal. A conforming implementation of C is allowed
to reject a program which declares main() that way.

But no "conforming implementation" on Windows rejects it! I don't
believe any C compiler anywhere would reject it.
I believe that gcc is available for Windows, and is conforming to the
C90 standard with the right options turned on, and conforms fairly well
with C99 with different options turned on. If, in addition, you turn on
the -pedantic-errors option, it rejects "void main()".

....
OK you're right I should remember that. However I don't think it's the
end of the world - the standard library is always linked in so the
right functions will be found in the end by the linker.
That's not true, in general. On most systems I've used, the part of the
standard library which is described in math.h is NOT always linked in;
you have to explicitly add the linker option -lm to link in the math
library. More esoterically, if you want to link C modules to a main
program written in Fortran (something I haven't had to do, but people I
work with do this all the time), the compiler will not automatically
tell the linker where to find the C libraries; you have to do that
explicitly yourself.

However, I wasn't talking about linking. I was talking about
compilation. In general, your code won't compile correctly without the
declarations that come from the appropriate standard library headers.
Those declarations are needed for the compiler to generate the correct
code for linking to the corresponding standard library functions. You
might have some "lucky" accidents with a particular compiler where
defective code appears to behave as you intended it to, but that same
code will not compile correctly under other implementations of C.
>Also, you're using feof() incorrectly, and until you understand why the
way that you're using it is incorrect, I would not recommend relying
upon any of your programs to function properly.

I don't really understand the problem with feof - it just checks if
the EOF indicator is set in a given FILE * struct. Anyway I'll read
about it.
Yes, do. The key point is that the EOF indicator is cleared when you
open the file; it's pointless to check it until you've started reading
the file. You should always check the return values from the functions
which read a file; if they indicate a failure, the requested data was
not actually read, and you shouldn't attempt to process it. If you've
already checked for failure from the reading functions, the only time
you actually need to use either feof() or ferror() is after you've had a
failure indication.
Dec 2 '07 #14
ra****@thisisnotmyrealemail.com said:
James Kuyper wrote:
>ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:

int x[256]; // frequencies
Global.

It's completely acceptable to have variables defined at file scope in
C!

What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they aren't
necessary in this case.

In this case they help simplify the code - the array gets initialized
to 0 at compile-time, instead of needing extra code for an
initialization loop bad for efficiency!
int main(void)
{
int x[256] = {0};
return 0;
}

This code takes advantage of the rules for partially-initialised aggregate
objects to set all x's ints to 0.

Why does everyone have this hangup about this? I took a class in C a
while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and BorLand.

That doesn't make it legal. A conforming implementation of C is allowed
to reject a program which declares main() that way.

But no "conforming implementation" on Windows rejects it!
Wrong. (And even if you were right, which you are not, the fact that an
implementation accepts faulty code does not imply that it must interpret
that code in the way you expect.)
I don't
believe any C compiler anywhere would reject it.
Your beliefs don't enter into it. Borland C rejects it when invoked in
conforming mode. So does gcc.
>...
I read the answers but mostly people only comment on trivial things
that aren't even errors! I'll be glad to have substantial comments on
my code.

Several of the "trivial" things people have commented on ARE errors, and
serious ones - you don't seem to understand how serious. Most
importantly, #inclusion of the appropriate standard headers is
absolutely essential for your code to even compile, at least under most
implentations of C. If what you've given us is the complete text of your
program, and if you are using a compiler which accepts your code as
written, junk it - it's teaching you some very bad habits.

OK you're right I should remember that. However I don't think it's the
end of the world - the standard library is always linked in so the
right functions will be found in the end by the linker.
Headers aren't about finding the functions. They are for making sure that
the function is being called in the right way.

>Also, you're using feof() incorrectly, and until you understand why the
way that you're using it is incorrect, I would not recommend relying
upon any of your programs to function properly.

I don't really understand the problem with feof - it just checks if
the EOF indicator is set in a given FILE * struct. Anyway I'll read
about it.
The normal way to use feof incorrectly is to assume that it is predictive.
It is not.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Dec 2 '07 #15
ra****@thisisnotmyrealemail.com writes:
Thanks again for all the suggestions, though I think some people are a
bit fussy in their answers.
No, you're entirely too fussy in your responses to the valuable
answers you're getting.
Here is a solution to Exercise 1.14. It deals well with control
characters too.
I don't believe that the code you posted is the same as the code
you're actually using. In most implementations you can get away with
calling an external function with no visible declaration (the compiler
will assume that the function returns int, and if it does, you just
might be ok). But they will *not* let you get away with referring to
external variables with no declaration.

Your calls to feof(), getchar(), and printf() just might happen to
work. Your reference to stdin would almost certainly cause the
compiler to reject your program.

I suspect that your actual code has the mandatory "#include <stdio.h>"
at the top, but you copy-and-pasted only part of the program when you
posted it.
// make histogram of character frequencies

int x[256]; // frequencies
This doesn't need to be global. You can declare

int x[256] = { 0 };

inside main().

Where does the number 256 come from? You seem to be assuming that
type char is 8 bits (not guaranteed), and that either that it's
unsigned or that you'll never encounter a character with a negative
value. When I added the "#include <stdio.h>" to your program and fed
it its own executable (a binary file), it died with a segmentation
fault, probably because it read a character with a negative value.

See the constant UCHAR_MAX, declared in <limits.h>. (getchar(), when
it doesn't return EOF, gives you a character value represented as an
unsigned char and then converted to int, so storing the result of
getchar() in an int would avoid the problem of negative values.)

The following references are to the comp.lang.c FAQ, available at
<http://www.c-faq.com/>. You would benefit greatly from reading the
whole thing.
void main()
Questions 11.12a, 11.12b, 11.14a, 11.14b, 11.15.
{
char c;
Question 12.1. (getchar() returns a result of type int; you're
storing the result in an object of type char, potentially losing
information.)
int i, y=0, z;
while(! feof(stdin) )
Question 12.2.
if(++x[c=getchar()]>y)
If c is negative, you attempt to modify an element outside the bounds
of the array x. If c exceeds 255 (as it can do on an implementation
with CHAR_BIT>8), the same thing can happen; you're not likely to run
into such an implementation, but it's easy enough to write portable
code.
y=x[z=c];
do {
for(i=0; i<256; i++)
Again, 256 is a "magic number". See UCHAR_MAX in <limits.h>
if(x[i]>0)
printf("%s", x[i]>y ? " * " : " ");
printf("\n");
} while(y--);
for(i=0; i<256; i++)
256 again.
if(x[i]>0)
if(i>32)
Where do you get the value 32? It happens to be the code for the ' '
character in ASCII. Your code will be much clearer if you use a
character constant ' ' rather than an integer constant 32.

Presumably the point is to determine whether i is a printable character.
Use the isgraph() function, declared in <ctype.h>, for this.
printf(" %c ", i);
else
printf("%02x ", i);
The use of "%02x" means that your output could be misaligned on a
system with characters bigger than 8 bits. That's probably not a big
problem.
printf("\n");
I recommend adding a "return 0;" here.
}
Finally, C allows multi-character identifiers for a very good reason.
Your use of x, y, z, i, and c makes your code difficult to read. The
names x, y, and z implies that these three variables are related in
some coherent manner (perhaps as coordinates), but they're not.
Consider naming your array something like "freq" or "frequencies".
I'm not going to take the time to figure out what "y" and "z" are
supposed to be.

You seem to value terseness over readability. This is not a good
choice. For example, you use braces only where they're absolutely
necessary; I prefer to use braces for all control statements, even
when only one statment is being controlled. For example, where you
write:

for(i=0; i<256; i++)
if(x[i]>0)
if(i>32)
printf(" %c ", i);
else
printf("%02x ", i);

I might write:

for (i = 0; i < 256; i++) {
if (x[i] 0) {
if (i 32) {
printf(" %c ", i);
}
else {
printf("%02x ", i);
}
}
}

It's a habit I picked up from Perl, which requires this, but it works
well in C. For one thing, it makes it easier to add an additional
statement if the braces are already there.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 2 '07 #16
Keith Thompson wrote:
ra****@thisisnotmyrealemail.com writes:
<snip>
> if(x[i]>0)
if(i>32)

Where do you get the value 32? It happens to be the code for the ' '
character in ASCII. Your code will be much clearer if you use a
character constant ' ' rather than an integer constant 32.

Presumably the point is to determine whether i is a printable
character. Use the isgraph() function, declared in <ctype.h>, for
this.
<snip>

Why not isprint() instead of isgraph()?

Dec 3 '07 #17
// make histogram of character frequencies
>
int x[256]; // frequencies
This can only give histogram of byte frequencies.
Because there are far more than 256 characters. (see www.unicode.org)
Dec 3 '07 #18
O_TEXT wrote:
>// make histogram of character frequencies

int x[256]; // frequencies

This can only give histogram of byte frequencies.
Because there are far more than 256 characters. (see www.unicode.org)
A C "byte" may be wider than 8 bits. In any case the behaviour of OP's
code is implementation defined, as soon as he goes beyond the basic
source and execution character set guaranteed by the C standard.

Dec 3 '07 #19
santosh a crit :
O_TEXT wrote:
>>// make histogram of character frequencies

int x[256]; // frequencies
This can only give histogram of byte frequencies.
Because there are far more than 256 characters. (see www.unicode.org)
A C "byte" may be wider than 8 bits.
By usual definition, a byte is exactly 8 bits.
In any case the behaviour of OP's
code is implementation defined, as soon as he goes beyond the basic
source and execution character set guaranteed by the C standard.
Most platforms works with ASCII character set.

Do you know many platforms which work with a character set not
compatible with ASCII?
How do you program with a variety of distincts characters on distincts
platforms with the standard C?
Dec 3 '07 #20
O_TEXT wrote:
santosh a écrit :
>O_TEXT wrote:
>>>// make histogram of character frequencies

int x[256]; // frequencies
This can only give histogram of byte frequencies.
Because there are far more than 256 characters. (see www.unicode.org)
>A C "byte" may be wider than 8 bits.

By usual definition, a byte is exactly 8 bits.
C's definition isn't the "usual" one; C's "bytes" are chars, and the
width of a `char` is implementation-defined.
>In any case the behaviour of OP's
code is implementation defined, as soon as he goes beyond the basic
source and execution character set guaranteed by the C standard.

Most platforms works with ASCII character set.
Some don't. The Standard doesn't exile such platforms (at least,
not for that reason).
Do you know many platforms which work with a character set not
compatible with ASCII?
ECBDIC; surely there are still EBCDIC implementations of C.
How do you program with a variety of distincts characters on distincts
platforms with the standard C?
Carefully, [locale] sensitively, and likely more and more unicodely.
It's just stuff.

--
Chris "not a wchar person" Dollin

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN

Dec 3 '07 #21
O_TEXT wrote:
santosh a crit :
....
>A C "byte" may be wider than 8 bits.

By usual definition, a byte is exactly 8 bits.
The usual definition is off-topic in this newsgroup, except insofar at
it needs to be mentioned as a contrast to the C standard's definition.
Dec 3 '07 #22
On Dec 1, 12:21 pm, raj...@thisisnotmyrealemail.com wrote:
Hello everyone,

Thanks again for all the suggestions, though I think some people are a
bit fussy in their answers.

Here is a solution to Exercise 1.14. It deals well with control
characters too.

// make histogram of character frequencies

int x[256]; // frequencies

void main()
int main(void)
{
char c;
int c; /* getchar() returns int */
int i, y=0, z;
while(! feof(stdin) )
if(++x[c=getchar()]>y)
y=x[z=c];
feof() will not return true until *after* you try to read past the end
of file. You should check against the result of getchar() first:

while ((c = getchar()) != EOF)
{
if (++x[c] y)
y = x[c]; /* z never gets used again, so we don't bother
with it */
}
if (c == EOF)
{
if (feof(stdin))
{
/* reached end-of-file condition */
}
else
{
/* Some other read error */
}
}

Also, years of experience have taught me that it's best to use
compound statements (i.e., braces) for all but the innermost scope of
a nested statement like that; it just makes things easier to read.
do {
for(i=0; i<256; i++)
if(x[i]>0)
printf("%s", x[i]>y ? " * " : " ");
printf("\n");
} while(y--);
for(i=0; i<256; i++)
if(x[i]>0)
if(i>32)
printf(" %c ", i);
else
printf("%02x ", i);
Again, I'd suggest using compound statements for all but the innermost
scope; it will just make things easier to follow in the future.
printf("\n");

}
Dec 3 '07 #23
santosh <sa*********@gmail.comwrites:
Keith Thompson wrote:
>ra****@thisisnotmyrealemail.com writes:
<snip>
>> if(x[i]>0)
if(i>32)

Where do you get the value 32? It happens to be the code for the ' '
character in ASCII. Your code will be much clearer if you use a
character constant ' ' rather than an integer constant 32.

Presumably the point is to determine whether i is a printable
character. Use the isgraph() function, declared in <ctype.h>, for
this.

<snip>

Why not isprint() instead of isgraph()?
Because the original program prints the hex code, not the character
itself, for the space character. isgraph() tests for printing
characters other than ' '.

--
Keith Thompson (The_Other_Keith) <ks***@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Dec 3 '07 #24
>santosh a crit :
>A C "byte" may be wider than 8 bits.
In article <fj**********@biggoron.nerim.netO_TEXT <O_****@nospam.frwrote:
>By usual definition, a byte is exactly 8 bits.
See <http://web.torek.net/torek/c/silliness.html:-)
>Most platforms works with ASCII character set.

Do you know many platforms which work with a character set not
compatible with ASCII?
Sure: a number of IBM mainframes use EBCDIC.
>How do you program with a variety of distincts characters on
distincts platforms with the standard C?
It is mostly a matter of finding assumptions about character sets
(such as the assumption that "all alphabetic characters are
contiguous") and cleaning them up. There is usually a tradeoff
involved -- you may need an extra lookup table here or there, for
instance -- but in general the cost of accomodating different
"native text" encodings is relatively low, especially when compared
with the cost of accomodating UTF-8, UTF-16, Unicode, and/or
"internationalization".
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Dec 3 '07 #25
On Sat, 1 Dec 2007 09:21:15 -0800 (PST),
ra****@thisisnotmyrealemail.com wrote:
>Hello everyone,

Thanks again for all the suggestions, though I think some people are a
bit fussy in their answers.

Here is a solution to Exercise 1.14. It deals well with control
characters too.
For some version of solution and deals well.
>
// make histogram of character frequencies

int x[256]; // frequencies

void main()
Trolling are you?
>{
char c;
int i, y=0, z;
while(! feof(stdin) )
And again?
if(++x[c=getchar()]>y)
If char defaults to signed, this will invoke undefined behavior just
after reading the last char (if you can generate an end of file
condition on stdin).
y=x[z=c];
What do you use z for?
do {
for(i=0; i<256; i++)
if(x[i]>0)
printf("%s", x[i]>y ? " * " : " ");
You viewing device supports 256 character on a single line?
printf("\n");
} while(y--);
for(i=0; i<256; i++)
if(x[i]>0)
if(i>32)
What do you think is magical about 32? My system has numerous
unprintable characters above that value.
printf(" %c ", i);
else
printf("%02x ", i);
printf("\n");
}

Remove del for email
Dec 4 '07 #26
On Sun, 2 Dec 2007 06:39:20 -0800 (PST),
ra****@thisisnotmyrealemail.com wrote:
>James Kuyper wrote:
>ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:

int x[256]; // frequencies
Global.

It's completely acceptable to have variables defined at file scope in
C!

What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they aren't
necessary in this case.

In this case they help simplify the code - the array gets initialized
to 0 at compile-time, instead of needing extra code for an
initialization loop bad for efficiency!
But you could achieve the same effect without any of the problems that
global variables cause simply by declaring the array static inside the
function.

snip
>OK you're right I should remember that. However I don't think it's the
end of the world - the standard library is always linked in so the
right functions will be found in the end by the linker.
The headers have very little to do with what the linker will link in
with your code and everything to do with the compiler generating
correct code. Leaving out stdlib.h and calling malloc introduces
undefined behavior. Leaving out string.h and passing anything other
than a void* or char* to memcpy or memset introduces undefined
behavior.

snip
Remove del for email
Dec 6 '07 #27
Barry Schwarz wrote, On 06/12/07 02:14:
On Sun, 2 Dec 2007 06:39:20 -0800 (PST),
ra****@thisisnotmyrealemail.com wrote:
>James Kuyper wrote:
>>ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:
>
>int x[256]; // frequencies
Global.
It's completely acceptable to have variables defined at file scope in
C!
What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they aren't
necessary in this case.
In this case they help simplify the code - the array gets initialized
to 0 at compile-time, instead of needing extra code for an
initialization loop bad for efficiency!

But you could achieve the same effect without any of the problems that
global variables cause simply by declaring the array static inside the
function.
That still has a number of the problems of global variables, just not
all of them.
>OK you're right I should remember that. However I don't think it's the
end of the world - the standard library is always linked in so the
right functions will be found in the end by the linker.

The headers have very little to do with what the linker will link in
with your code and everything to do with the compiler generating
correct code. Leaving out stdlib.h and calling malloc introduces
undefined behavior. Leaving out string.h and passing anything other
than a void* or char* to memcpy or memset introduces undefined
behavior.
Actually, any call to memcpy or memset without a declaration in scope
invokes undefined behaviour even if you pass void* parameters. This is
because the return type is void*, and the return type being wrong causes
undefined behaviour even if you do not use the value returned. I can
even think of ways it could cause problems!
--
Flash Gordon
Dec 6 '07 #28
Groovy hepcat ra****@thisisnotmyrealemail.com was jivin' in comp.lang.c
on Mon, 3 Dec 2007 1:39 am. It's a cool scene! Dig it.
James Kuyper wrote:
>ra****@thisisnotmyrealemail.com wrote:
Johannes Bauer wrote:
ra****@thisisnotmyrealemail.com schrieb:

int x[256]; // frequencies
Global.

It's completely acceptable to have variables defined at file scope
in C!

What's acceptable is not always a good idea. Global objects have many
disadvantages; they should be avoided except when necessary; they
aren't necessary in this case.

In this case they help simplify the code - the array gets initialized
to 0 at compile-time, instead of needing extra code for an
initialization loop bad for efficiency!
Others have shown you how to initialise block scope arrays. The
generated object code may simply be a loop in which elements are
assigned a given value. In that case initialisation may be no more
efficient than a loop you write yourself. This is also true of the
implicit initialisation of a file scope array.
Code that makes extensive use of things like global variables is often
called "spaghetti code". Only meat ball programmers write code like
that.
Why does everyone have this hangup about this? I took a class in C
a while back and my teacher always used void main() { ... }. I can
confirm that it works fine with both MicroSoft compiler and
BorLand.

That doesn't make it legal. A conforming implementation of C is
allowed to reject a program which declares main() that way.

But no "conforming implementation" on Windows rejects it! I don't
believe any C compiler anywhere would reject it.
Let's test that assertion, shall we? I reboot to Windoze (because I'm
using Linux), open a console window and enter these lines:

-----------------------------------------------------------------------
copy con testing.c
#include <stdio.h>

void main(void)
{
puts("Hello, World!");
}
^z
bcc32 -A -etesting.exe -w testing.c
-----------------------------------------------------------------------

The resulting output from Borland Builder is as follows:

-----------------------------------------------------------------------
Borland C++ 5.3 for Win32 Copyright (c) 1993, 1998 Borland International
testing.c:
Error testing.c 4: main must have a return type of int in function main
*** 1 errors in Compile ***
-----------------------------------------------------------------------

That's an error message (which halts compilation), not merely a warning
(which allows compilation to continue). When invoked with the -A
command line option (which forces it to be standard compliant) the
Borland compiler rejects void as a return type for main(). Not only has
"any C compiler anywhere" rejected it, but a "'conforming
implementation' on Windows" has rejected it.
Clearly, therefore, you are wrong.
I read the answers but mostly people only comment on trivial things
that aren't even errors! I'll be glad to have substantial comments
on my code.

Several of the "trivial" things people have commented on ARE errors,
and serious ones - you don't seem to understand how serious. Most
importantly, #inclusion of the appropriate standard headers is
absolutely essential for your code to even compile, at least under
most implentations of C. If what you've given us is the complete text
of your program, and if you are using a compiler which accepts your
code as written, junk it - it's teaching you some very bad habits.

OK you're right I should remember that. However I don't think it's the
end of the world - the standard library is always linked in so the
right functions will be found in the end by the linker.
Who says? The library may not be linked without the compiler magic
contained in the headers. Or they may be linked, but functions not
called properly. The point is that failing to include the proper
headers is a very serious error, and you must understand this.
>Also, you're using feof() incorrectly, and until you understand why
the way that you're using it is incorrect, I would not recommend
relying upon any of your programs to function properly.

I don't really understand the problem with feof - it just checks if
the EOF indicator is set in a given FILE * struct. Anyway I'll read
about it.
Many newbies think feof()'s purpose is to indicate when the end of a
file is reached by a read function. This is incorrect. Its purpose is
to indicate when a file stream's end of file indicator is set. This
only happens when you try to read from a stream that has *already*
reached the end. To explain this more clearly, consider the following
situation.
Suppose you have a stream containing three bytes, and you are reading
one byte at a time, using getchar(), in a loop, like so:

while(!feof(stdin))
{
c = getchar();
putchar(c);
}

On the first iteration of the loop you test the end of file indicator
for the input stream (stdin in this example), and it is not set, so you
then read the first byte and write this out. On the second iteration of
the loop you test the end of file indicator again, and it is not set,
so you then read the second byte and write this out. On the third
iteration of the loop you test the end of file indicator again, and it
is not set, so you then read the third byte and write this out. So far
so good. But the end of file indicator is still *not* set, and feof()
will return false. So you iterate a fourth time and try another read.
The read fails, of course, because there are no more bytes in the
stream. This is the perfect time to exit the loop; and since getchar()
returns EOF to indicate that it failed to read a byte, you have the
perfect way to detect this situation. However, you ignore this value
and simply continue processing the (now invalid) data you think you've
read from the file. You send EOF to stdout. *Now* the end of file
indicator is set, and feof() returns true. But it's too late. You don't
test for this until the beginning of the fifth iteration, *after*
you've used the invalid data. You've read in three valid bytes and
written out four bytes, one of which is not valid.
What you should be doing is this:

int c; /* c must be an int so we can detect EOF. */

while(EOF != (c = getchar()))
{
putchar(c);
}
if(!feof(stdin)) /* Or we could use if(ferror(stdin)). */
{
/* File read error: handle it somehow. */
}

Here we attempt to read a byte with getchar(), and only enter the loop
if the return value does not indicate a failure to read a byte. After
the failure code (EOF) has been detected, the loop is exited, and we
then attempt to determine whether the failure occurred due to an error
or an end of file condition. Here's a breakdown of how it works (using
the same 3 byte example input as before).
On the first iteration we read the first byte and test whether the
read was successful. It was, so we output the byte. On the second
iteration we read the second byte and test whether the read was
successful. It was, so we output the byte. On the third iteration we
read the third byte and test whether the read was successful. It was,
so we output the byte. On the fourth iteration we read a byte, but the
stream is exhausted and the read fails; getchar() returns EOF. We
detect this and exit the loop. We've read in three valid bytes and
written out three bytes, all of which are valid. *Now* we call feof()
to test whether the failure was due to an end of file condition, and,
if so, skip the error handling code. However, if feof() returns false,
then the read failure must have been due to an error, in which case we
handle the error somehow (perhaps by emitting a diagnostic message and
quitting).

--
Dig the sig!

----------- Peter 'Shaggy' Haywood ------------
Ain't I'm a dawg!!
Dec 7 '07 #29
RoS
In data Fri, 07 Dec 2007 00:52:19 +1100, Peter 'Shaggy' Haywood
scrisse:
>while(!feof(stdin))
{
c = getchar();
putchar(c);
}

On the first iteration of the loop you test the end of file indicator
for the input stream (stdin in this example), and it is not set, so you
then read the first byte and write this out. On the second iteration of
the loop you test the end of file indicator again, and it is not set,
so you then read the second byte and write this out. On the third
iteration of the loop you test the end of file indicator again, and it
is not set, so you then read the third byte and write this out. So far
so good. But the end of file indicator is still *not* set, and feof()
will return false. So you iterate a fourth time and try another read.
The read fails, of course, because there are no more bytes in the
stream. This is the perfect time to exit the loop; and since getchar()
returns EOF to indicate that it failed to read a byte, you have the
perfect way to detect this situation. However, you ignore this value
and simply continue processing the (now invalid) data you think you've
read from the file. You send EOF to stdout. *Now* the end of file
indicator is set, and feof() returns true. But it's too late. You don't
test for this until the beginning of the fifth iteration, *after*
you've used the invalid data. You've read in three valid bytes and
written out four bytes, one of which is not valid.
What you should be doing is this:

int c; /* c must be an int so we can detect EOF. */

while(EOF != (c = getchar()))
{
putchar(c);
}
if(!feof(stdin)) /* Or we could use if(ferror(stdin)). */
{
/* File read error: handle it somehow. */
}
so what is right?

while(1)
{
c = getchar();
if( feof(stdin) || ferror(stdin) ) break;
putchar(c);
}

or

while(1)
{
c = getchar();
if( feof(stdin) ) break;
putchar(c);
}

while(1)
{
c = getchar();
if( ferror(stdin) ) break;
putchar(c);
}

or no one of above

thank you
>Here we attempt to read a byte with getchar(), and only enter the loop
if the return value does not indicate a failure to read a byte. After
the failure code (EOF) has been detected, the loop is exited, and we
then attempt to determine whether the failure occurred due to an error
or an end of file condition. Here's a breakdown of how it works (using
the same 3 byte example input as before).
On the first iteration we read the first byte and test whether the
read was successful. It was, so we output the byte. On the second
iteration we read the second byte and test whether the read was
successful. It was, so we output the byte. On the third iteration we
read the third byte and test whether the read was successful. It was,
so we output the byte. On the fourth iteration we read a byte, but the
stream is exhausted and the read fails; getchar() returns EOF. We
detect this and exit the loop. We've read in three valid bytes and
written out three bytes, all of which are valid. *Now* we call feof()
to test whether the failure was due to an end of file condition, and,
if so, skip the error handling code. However, if feof() returns false,
then the read failure must have been due to an error, in which case we
handle the error somehow (perhaps by emitting a diagnostic message and
quitting).
Dec 9 '07 #30
On 9 Dec, 06:51, RoS <R...@not.existwrote:
so what is right?
<snip bad code>
>
or no one of above
None of the above. Try:

while( EOF != ( c = getchar())) {
/* ... */
}

/* Now check feof() and ferror() */
Dec 9 '07 #31
RoS
In data Sun, 9 Dec 2007 00:10:13 -0800 (PST), William Pursell
scrisse:
>On 9 Dec, 06:51, RoS <R...@not.existwrote:
>so what is right?
<snip bad code>
>>
or no one of above

None of the above. Try:
why "none"?
while(1)
{int c=getchar();
if(feof(stdin)||ferror(stdin)) break;
.....
}

at last should be ok
>while( EOF != ( c = getchar())) {
/* ... */
}

/* Now check feof() and ferror() */
Dec 9 '07 #32
RoS wrote:
In data Sun, 9 Dec 2007 00:10:13 -0800 (PST), William Pursell
scrisse:
>On 9 Dec, 06:51, RoS <R...@not.existwrote:
>>so what is right?
<snip bad code>
>>or no one of above
None of the above. Try:

why "none"?
while(1)
{int c=getchar();
if(feof(stdin)||ferror(stdin)) break;
....
}
It will work, but it's not the right way to do it. There's no point in
wasting time checking feof() or ferror() unless c is EOF, something your
code doesn't even bother to check for. As a secondary matter, your way
of dealing with this treats feof(), which is normal, the same way as
ferror(), which indicates that something has gone wrong. That's
generally a bad design decision.
Dec 9 '07 #33
Chris Torek a écrit :
>santosh a 閏rit :
>>A C "byte" may be wider than 8 bits.

In article <fj**********@biggoron.nerim.netO_TEXT <O_****@nospam.frwrote:
>By usual definition, a byte is exactly 8 bits.

See <http://web.torek.net/torek/c/silliness.html:-)
Okay. English language use undefined words to deals with undefined concept.

However, I use the word byte to deal with the translation of what is
called «octet» in french language.

This URL on a page which deals of bytes which are not eight bits seams
to be C spcecific. Isn't it?

For example, in java language, a byte is a eight bits data.

>Most platforms works with ASCII character set.

Do you know many platforms which work with a character set not
compatible with ASCII?

Sure: a number of IBM mainframes use EBCDIC.
Okay. But is is for very few computers isn't it?

Did IBM planned to migrate their computer, to EBCDIC-UTF8?

Did IBM mainframes activity be bought by Lenovo?
>How do you program with a variety of distincts characters on
distincts platforms with the standard C?

It is mostly a matter of finding assumptions about character sets
(such as the assumption that "all alphabetic characters are
contiguous") and cleaning them up. There is usually a tradeoff
involved -- you may need an extra lookup table here or there, for
instance --
I do not understand well neither this point...
but in general the cost of accomodating different
"native text" encodings is relatively low, especially when compared
with the cost of accomodating UTF-8, UTF-16, Unicode, and/or
"internationalization".
.... nor this one.
Might be because I believe that accommodating is done by Unicode.
Dec 10 '07 #34
O_TEXT wrote:
Chris Torek a écrit :
>>santosh a 閏rit :
A C "byte" may be wider than 8 bits.

In article <fj**********@biggoron.nerim.netO_TEXT <O_****@nospam.fr>
wrote:
>>By usual definition, a byte is exactly 8 bits.

See <http://web.torek.net/torek/c/silliness.html:-)

Okay. English language use undefined words to deals with undefined concept.

However, I use the word byte to deal with the translation of what is
called «octet» in french language.
It is also called an octet in English. However, most people are
unfamiliar with that word, and use byte as if it were a synonym for
octet. The C standard clearly says otherwise, and it is the C standard's
meaning that should be used when discussing C, but even most C
programmers are unaware of the distinction.
This URL on a page which deals of bytes which are not eight bits seams
to be C spcecific. Isn't it?
>>Most platforms works with ASCII character set.

Do you know many platforms which work with a character set not
compatible with ASCII?

Sure: a number of IBM mainframes use EBCDIC.

Okay. But is is for very few computers isn't it?
It doesn't matter. The C standard was deliberately designed to leave a
great deal of room for implementors to choose whichever character
encoding they wish. Unnecessarily building a reliance on a particular
character encoding into your program is a bad idea, even if it is
overwhelmingly the most popular encoding. And, while character sets that
are (to varying degrees) compatible with one or more of the national
variants of ASCII are indeed commonplace, there's nothing close to a
single universally accepted character set at this time.
>but in general the cost of accomodating different
"native text" encodings is relatively low, especially when compared
with the cost of accomodating UTF-8, UTF-16, Unicode, and/or
"internationalization".

... nor this one.
Might be because I believe that accommodating is done by Unicode.
Accommodating systems that don't support Unicode is also an issue.
Dec 10 '07 #35
Groovy hepcat RoS was jivin' in comp.lang.c on Sun, 9 Dec 2007 5:51 pm.
It's a cool scene! Dig it.
In data Fri, 07 Dec 2007 00:52:19 +1100, Peter 'Shaggy' Haywood
scrisse:
> What you should be doing is this:

int c; /* c must be an int so we can detect EOF. */

while(EOF != (c = getchar()))
{
putchar(c);
}
if(!feof(stdin)) /* Or we could use if(ferror(stdin)). */
{
/* File read error: handle it somehow. */
}

so what is right?

while(1)
{
c = getchar();
if( feof(stdin) || ferror(stdin) ) break;
putchar(c);
}

or

while(1)
{
c = getchar();
if( feof(stdin) ) break;
putchar(c);
}

while(1)
{
c = getchar();
if( ferror(stdin) ) break;
putchar(c);
}

or no one of above
Neither of the scenarios you have given. But I have shown you what to
do. Please read the portion of my previous reply that I have quoted
above (beginning with "What you should be doing is this:"). Here's how
it works:

while(EOF != (c = getchar()))

Here we read in a byte with getchar(). If the read fails, getchar()
returns EOF (which is a negative integer constant that compares unequal
to any valid character value). Each iteration of the loop, its
controlling expression tests for this value and, if EOF is detected,
quits the loop without entering the body.

{
putchar(c);
}

Here in the body of the loop (if entered), all we do is output the
character.
It may help you to understand what's going on if I write it a slightly
different way. The loop as shown above is equivalent to this:

c = getchar();
while(EOF != c)
{
putchar(c);
c = getchar();
}

First we read a character. Next we test whether the read succeeded by
testing for EOF. If the read was successful, the body is entered, and
we output the character then read another. We go back to the top of the
loop and test whether that read was successful. If so, we enter the
body, output the character and read another. And so on.

if(!feof(stdin))

Once we've quit looping, we then use feof() to test for an end of file
condition. If feof() does not return true, then we're not at the end of
the file/stream. In that case, the read failure must have been due to
an error, so we handle it:

{
/* File read error: handle it somehow. */
}

Alternatively, you could use ferror() to test for an error in the
stream, rather than using feof(). This is the method I prefer.

if(ferror(stdin))
{
/* File read error: handle it somehow. */
}

This approach also works with functions that read more than one byte
at a time, such as fprintf() and fread(). For example:

char buf[100];

while(NULL != fgets(buf, sizeof buf, stdin))
{
fputs(buf, stdout);
}
if(ferror(stdin))
{
/* File read error: handle it somehow. */
}

--
Dig the sig!

----------- Peter 'Shaggy' Haywood ------------
Ain't I'm a dawg!!
Dec 11 '07 #36

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.