[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Re: need some help with this histogram of words program........

io_x

2/11/2011 8:52:00 PM


"Ceriousmall" <> ha scritto nel messaggio
news:948c9c67-82b2-471c-b52d-515c26b61d32@e9g2000vbi.googlegroups.com...
your code i did not understand much but
your program has a bug for me
if the input is somethig like
aaaa\n
hh^Z
where <ctrl-z>==^Z is the end of the input
it not find the 2 letter word hh


1| *
+------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20++

instead this is my prog output with the same input:
+-------------------- -------------------
1:
2:-
3:
4:-
5:
etc
there are 2 words (for the thefinition of word in text file)
one of 2 char and one of 4 chars



16 Answers

Ceriousmall

2/12/2011 2:38:00 AM

0

On Feb 11, 4:51 pm, "io_x" <a...@b.c.invalid> wrote:
> "Ceriousmall" <> ha scritto nel messaggionews:948c9c67-82b2-471c-b52d-515c26b61d32@e9g2000vbi.googlegroups.com...
> your code i did not understand much but
> your program has a bug for me
> if the input is somethig like
> aaaa\n
> hh^Z
> where <ctrl-z>==^Z is the end of the input
> it not find the 2 letter word hh
>
>  1|           *
>   +------------------------------------------------------------
>      1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20++
>
> instead this is my prog output with the same input:
>   +-------------------- -------------------
>  1:
>  2:-
>  3:
>  4:-
>  5:
>  etc
> there are 2 words (for the thefinition of word in text file)
> one of 2 char and one of 4 chars



Ok......... that's very interesting.........I'm forced to revisit that
code................

Ceriousmall

2/13/2011 6:36:00 AM

0

On Feb 11, 4:51 pm, "io_x" <a...@b.c.invalid> wrote:
> "Ceriousmall" <> ha scritto nel messaggionews:948c9c67-82b2-471c-b52d-515c26b61d32@e9g2000vbi.googlegroups.com...
> your code i did not understand much but
> your program has a bug for me
> if the input is somethig like
> aaaa\n
> hh^Z
> where <ctrl-z>==^Z is the end of the input
> it not find the 2 letter word hh
>
>  1|           *
>   +------------------------------------------------------------
>      1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20++
>
> instead this is my prog output with the same input:
>   +-------------------- -------------------
>  1:
>  2:-
>  3:
>  4:-
>  5:
>  etc
> there are 2 words (for the thefinition of word in text file)
> one of 2 char and one of 4 char
.
.
.
Ok this is my revisited code, I believe this should solve the bug as
stated above............

/* Program prints a histogram of the length of words in its input */

#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define LIMIT 20 /* horizontal scale & word size limits */
#define VERLIMIT 1000 /* verticle scale limit */

int main(void)
{
int c, i, x;
int nchar, mark_scale, terminate;
int mark[LIMIT+1];
long wordlength[LIMIT+1];

nchar = 0;
mark_scale = FALSE;
terminate = FALSE;

for (i = 0; i <= LIMIT; ++i) {
wordlength[i] = 0;
mark[i] = FALSE;
}
while ((c = getchar()) && terminate == FALSE) {
if (c >= '0' && c <= '9')
printf("digit %d not valid for a word. . .\n", c-'0');
else if (c == ' ' || c == '\n' || c == '\t') {
if (nchar > 0 && nchar < LIMIT)
++wordlength[nchar];
else if (nchar >= LIMIT)
++wordlength[LIMIT];
nchar = 0;
}
else
++nchar;
if (c == EOF)
terminate = TRUE;
}
for (i = VERLIMIT; i >= 1; --i) {
for (x = 1; x <= LIMIT; ++x)
if (wordlength[x] == i)
mark_scale = TRUE;

if (mark_scale != FALSE)
printf("%4d|", i);

for (x = 1; x <= LIMIT; ++x)
if (wordlength[x] == i) {
printf("%3c", 'Ü');
mark[x] = TRUE;
}
else if (mark[x] == FALSE)
printf("%3c", ' ');
else
printf("%3c", 'Ü');
printf("\n");
}
printf(" +");
for (i = 1; i <= LIMIT*3; ++i)
printf("-");

printf("\n ");
for (i = 1; i <= LIMIT; ++i)
printf("%3d", i);

printf("++\n");

return 0;
}


_______________________________________________
Ceriously
I'm really beginning to C the code now. . . . .

Ian Collins

2/13/2011 7:07:00 AM

0

On 02/13/11 07:35 PM, Ceriousmall wrote:
> ..
> Ok this is my revisited code, I believe this should solve the bug as
> stated above............
>
> /* Program prints a histogram of the length of words in its input */
>
> #include<stdio.h>
>
> #define TRUE 1
> #define FALSE 0
> #define LIMIT 20 /* horizontal scale& word size limits */
> #define VERLIMIT 1000 /* verticle scale limit */
>
> int main(void)
> {
> int c, i, x;
> int nchar, mark_scale, terminate;
> int mark[LIMIT+1];
> long wordlength[LIMIT+1];
>
> nchar = 0;
> mark_scale = FALSE;
> terminate = FALSE;

A lot of these are only used within a loop, declaring them at the start
of the loop would make the code easier to read.

> for (i = 0; i<= LIMIT; ++i) {
> wordlength[i] = 0;
> mark[i] = FALSE;
> }
> while ((c = getchar())&& terminate == FALSE) {
> if (c>= '0'&& c<= '9')
> printf("digit %d not valid for a word. . .\n", c-'0');

Why? Try running the program with the source as the input!

> else if (c == ' ' || c == '\n' || c == '\t') {

Why not use isspace(c)?

> if (nchar> 0&& nchar< LIMIT)
> ++wordlength[nchar];
> else if (nchar>= LIMIT)
> ++wordlength[LIMIT];
> nchar = 0;
> }
> else
> ++nchar;
> if (c == EOF)
> terminate = TRUE;

You should test for EOF as early as possible, in the while condition
would be best.

> }
> for (i = VERLIMIT; i>= 1; --i) {

Given a large value for VERLIMIT, this will print a lot of blank lines.
it might be better to track the maximum count in a bucket and use that
here.

--
Ian Collins

Ike Naar

2/13/2011 9:34:00 AM

0

On 2011-02-13, Ian Collins <ian-news@hotmail.com> wrote:
> On 02/13/11 07:35 PM, Ceriousmall wrote:
>> else if (c == ' ' || c == '\n' || c == '\t') {
>
> Why not use isspace(c)?

It's not the same.
isspace() also includes carriage return, form feed and vertical tab.

Ian Collins

2/13/2011 9:42:00 AM

0

On 02/13/11 10:34 PM, Ike Naar wrote:
> On 2011-02-13, Ian Collins<ian-news@hotmail.com> wrote:
>> On 02/13/11 07:35 PM, Ceriousmall wrote:
>>> else if (c == ' ' || c == '\n' || c == '\t') {
>>
>> Why not use isspace(c)?
>
> It's not the same.
> isspace() also includes carriage return, form feed and vertical tab.

All of which separate words.

--
Ian Collins

Ben Bacarisse

2/13/2011 2:45:00 PM

0

Ian Collins <ian-news@hotmail.com> writes:

> On 02/13/11 07:35 PM, Ceriousmall wrote:
<snip>
>> else if (c == ' ' || c == '\n' || c == '\t') {
>
> Why not use isspace(c)?

Ceriousmall seems to be on chapter 1. The isxxx macros are not
introduced until later. Indeed, K&R use c == ' ' || c == '\n' || c ==
'\t' in a word counting example in chapter 1 so it is the obvious choice
at this stage.

<snip>
--
Ben.

Ceriousmall

2/13/2011 3:50:00 PM

0

On Feb 13, 10:45 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Ian Collins <ian-n...@hotmail.com> writes:
> > On 02/13/11 07:35 PM, Ceriousmall wrote:
> <snip>
> >>                else if (c == ' ' || c == '\n' || c == '\t') {
>
> > Why not use isspace(c)?
>
> Ceriousmall seems to be on chapter 1.  The isxxx macros are not
> introduced until later.  Indeed, K&R use c == ' ' || c == '\n' || c ==
> '\t' in a word counting example in chapter 1 so it is the obvious choice
> at this stage.
>
> <snip>
> --
> Ben.

.
.
.
Thank U Ben indeed.... page 28 Character arrays to be
precise............... this forum is my link too other C programmers
and all the help is greatly appreciated....

Ben Bacarisse

2/13/2011 5:12:00 PM

0

Ceriousmall <divadsmall@gmail.com> writes:

> On Feb 11, 4:51 pm, "io_x" <a...@b.c.invalid> wrote:
>> "Ceriousmall" <> ha scritto nel messaggionews:948c9c67-82b2-471c-b52d-515c26b61d32@e9g2000vbi.googlegroups.com...
>> your program has a bug for me
>> if the input is somethig like
>> aaaa\n
>> hh^Z
>> where <ctrl-z>==^Z is the end of the input
>> it not find the 2 letter word hh
<snip>
> Ok this is my revisited code, I believe this should solve the bug as
> stated above............

The end result is worse, I think.

<snip>
> while ((c = getchar()) && terminate == FALSE) {
> if (c >= '0' && c <= '9')
> printf("digit %d not valid for a word. . .\n", c-'0');
> else if (c == ' ' || c == '\n' || c == '\t') {
> if (nchar > 0 && nchar < LIMIT)
> ++wordlength[nchar];
> else if (nchar >= LIMIT)
> ++wordlength[LIMIT];
> nchar = 0;
> }
> else
> ++nchar;
> if (c == EOF)
> terminate = TRUE;

First, using an assignment in a larger expression but where the value is
to be ignored is very peculiar. It's likely to confuse people. What is
more, a null byt will terminate the loop which might surprise the user
even more.

Secondly, putting the ch = getchar() test *before* the other half of the
&& means that, on some systems, EOF no longer works. After detecting
EOF you try to read again. It's best to do any more input once you've
seen EOF and you can do that by switching the && order:

terminate == FALSE && (c = getchar())

However you should really put the c = getchar() at the start of the loop
body.

If you do that, you'll see that ch == EOF exactly mirrors the value of
'terminate' so there is no need for that exatr variable. Instead you
could write:

ch = 0; /* anything but EOF */
while (ch != EOF) {
ch = getchar();
/* The rest of your body but without the last 'if' */
}

But, finally, C has a loop for exactly this kind of pattern: do
.... while. So I'd write:

do {
ch = getchar();
/* The rest of your body but without the last 'if' */
} while (ch != EOF) {

The end result is simpler.

Rather then just say "use a do loop" I've tried to show you can be
thinking about your programs be showing you a sequences of small
improvements.

<snip>
--
Ben.

Ben Bacarisse

2/14/2011 1:47:00 AM

0

Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
<snip>
Typo city. For
> Rather then just say "use a do loop" I've tried to show you can be
> thinking about your programs be showing you a sequences of small
> improvements.
read:

Rather then just saying "use a do loop" I've tried to show you how you
could be thinking about your programs by showing you a sequences of small
improvements (that gets you to the same endpoint).

--
Ben.

Ceriousmall

2/14/2011 4:05:00 AM

0

On Feb 13, 9:46 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Ben Bacarisse <ben.use...@bsb.me.uk> writes:
>
> <snip>
> Typo city.  For> Rather then just say "use a do loop" I've tried to show you can be
> > thinking about your programs be showing you a sequences of small
> > improvements.
>
> read:
>
> Rather then just saying "use a do loop" I've tried to show you how you
> could be thinking about your programs by showing you a sequences of small
> improvements (that gets you to the same endpoint).
>
> --
> Ben.

.
.
.
Thanks Ben very helpful and insightful info. It's amazing what a
difference in perspective can do...........