Word length program

Pages: 12
Hello,

I am supposed to write a program to print a histogram of the lengths of words in it`s input.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#include <stdio.h>

int main()

{

int c, i, state;
state = 0;
int length [100];

  for (i=0; i<length; ++i)

   length[i] = 0;            // initialize elements

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

      if (c!= ' ' || c!= '\n' || c!= '\t')
    {
      state = 1;
      ++ length[i]; 
    }

     else if (state == 1)

    {
       state = 0;   
       -- length[i];
    }
  
  }


  printf( "histogram:");
     for (i=0; i<length[i]; ++i)
 printf( "%c", length[i]);
 printf("\n");
    
}



When I run that I get error " comparison between pointer and integer ".
Thank you for help,


-Richard
Line 12: you cannot use the name of an array as its length. I do not know why you decided to call your array "length" - it is a deceptive name.

Also, you accidentally wrote your program in C instead of C++. You may want to fix that.
Last edited on
It`s all part of my plan, I`m doing a self study of the C programming language.

I corrected the line 12 mistake but now when I compile it`s throwing me some junk value :)
What is your current code?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

#include <stdio.h>

int main()

{

int c, i, word, inspace;
state = 0;
int length [100];

  for (i=0; i<100; ++i)

   length[i] = 0;            // initialize elements

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

      if (c != ' ' && c != '\t' && c != '\n')
    {
      if (inspace == 0) 
         {
            inspace = 1;
            ++ length[i];
         }
    }

     else  
	     {
		   inspace = 0;
		   -- length[i];
	     }

    {
       state = 0;   
       -- length[i];
    }
  
  }


  printf( "histogram:");
     for (i=0; i<length[i]; ++i)
 printf( "%c", length[i]);
 printf("\n");
    
}
There's a number of errors in your code. First off, your while loop will only write length values to the length array at its last index. Do you know why? Secondly, your conditional statements within the loop most certainly are not doing what you want them to. Can you explain, in words, what your program has to do in the loop to count the length of each word it encounters in the string? Can you write that in psuedocode?

Side note, I'm not sure if this was intentional but you're making a finite state machine. If it wasn't intentional, I recommend Googling "finite state machine", you'll find them very helpful.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

#include <stdio.h>

int main()

{

int c, i, j, word, inspace;
word = 0;
inspace = 0;
int length [100];

  for (i=0; i<100; ++i)
  length[i] = 0;            // initialize elements
  i = 0;
  

   while ((c = getchar()) != EOF && word<=100) {

      if (c != ' ' && c != '\t' && c != '\n') 
      
      ++length[i];
      inspace = 1;
      
      if (c == ' ' || c == '\t' || c == '\n')
      
      {  
        if (inspace = 1) 
        
        inspace = 0;
        --length[i];  
        ++word;
        
       }
      
      
   printf( "histogram:");
  
 for (j = 0; j < length[i]; ++j)
 printf("*");
 printf("\n");
    
  }


}




The logic is pretty simple : If we encounter a non-whitespace character we in a word array and increment it. Else we are out of the word and decrement it.
Try running the logic you just described in your head. How many different lengths will that keep track of? Will those length(s) actually be the lengths of the words in the string?

Also, you need to put brackets {...} around your conditional statements if they're going to have more than one line in them. And on line 28 you used an assignment operator instead of comparison operator (==)
This follows quite well the original structure of the program and is simple enough itself, though does`t compile very well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


#include <stdio.h>

int main()

{

int c, i, j, word, inspace, length;
length = 0;
word = 0;
inspace = 0;
int lengths [20];

  for (i=0; i<20; ++i)
  lengths[i] = 0;            // initialize elements
  i = 0;
  

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

      if (c != ' ' && c != '\t' && c != '\n') {
      
      ++length;
      inspace = 1;
      if (length < 100)
      {
      ++lengths[length];
      }
       
      }
       
      if (c == ' ' || c == '\t' || c == '\n')
      
      {  
        if (inspace == 1) 
        
        inspace = 0;
        ;  
        ++word;
        
       }
      
   }
   
   printf( "histogram:");
  for (i=0; i<20; ++i)     {
 printf( "%2d", i);
 for (j = 0; j < lengths[i]; ++j)
    printf("*");
    printf("\n");
    
   }
}

		 
















Last edited on
here we gohistogram: 0
1*
2*
3*
4*
5*
6*
7*
8*
9
10
11
12
13
14
15
16
17
18
19
You're definitely getting there. Look at your code, is the inspace variable really necessary? (hint: Do you use it anywhere except where you're assigning it?). Also, should you increment the length variable when you hit white space or non white space?

Should I maybe increment this index = i when I hit white space?

Here are some changes I did:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

#include <stdio.h>

int main()

{

int c, i, j, word, inspace, length;
length = 0;
word = 0;
inspace = 0;
int lengths [20];

  for (i=0; i<20; ++i)
  lengths[i] = 0;            // initialize elements
  i = 0;
  

   while ((c = getchar()) != EOF  && word < 20) {
     
      if (c == ' ' || c == '\t' || c == '\n')
      
      {  
        
        
        inspace = 0;
        ++i;  
        ++word;
        
      }
      
   

      if (c != ' ' && c != '\t' && c != '\n') {
        
       if (inspace == 0)   {
      
        inspace == 1;
        ++lengths[length];
      
       }
       
   }
       
     
   
   printf( "histogram:");
  for (i=0; i<20; ++i)     {
 printf( "%2d", i);
 for (j = 0; j < lengths[i]; ++j)
    printf("*");
    printf("\n");
    
   }
}

Last edited on
Maybe you'll benefit more if I explain how I would do it, in words. I would have an array of int's, like you have now. Each index of the array would represent the length of the n'th word. In addition to the array, I would have 2 separate variables. One would store the amount of words found, therefor it would start at 0 and be incremented each time whitespace is hit. The second variable would store the length of the current word and would be incremented each time a non-whitespace character is hit. When whitespace is hit, it's value would be copied into the the index of the array given by the first variable (before the first variable is incremented) then reset to 0. When finished, you would have an array whose elements store the lengths of the words, in the order that words in the input are, and a variable indicating how many words were in the input (and thus, which index to go up to when outputting the results).


Here is something that I generated:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

#include <stdio.h>

int main()

{

int c, i, j, word, current_word_length, state;
wordn = 0;
word = 0;
state = 0;
int lengths [20];

  for (i=0; i<20; ++i)
  length[i] = 0;            // initialize elements
  i = 0;
  

   while ((c = getchar()) != EOF  && word < 20) {
     
      if (c == ' ' || c == '\t' || c == '\n')
      
      {  
        
        
        state = 0;
       
        length[current_word_length] = length[i]
        ++i;                  
        ++wordn;
        
      }
      
   

      if (c != ' ' && c != '\t' && c != '\n') {
        
       if (state == 0) {
      
        state == 1;
        ++ current_word_length;                        // increment word variable
        ++ length[current_word_length];
       }
       
   }
       
     
   
   printf( "histogram:");
  for (i=0; i<20; ++i)     {
 printf( "%2d", i);
 for (j = 0; j < lengths[i]; ++j)
    printf("*");
    printf("\n");
    
   }
}
Last edited on
On line 14 you need brackets around those 2 statements that I'm assuming you want in the for loop. Line 40 does nothing at all, as you're using the comparison operator but then never using the result of the comparison. Look carefully at your code, does it do what my previous post outlines? Do I ever mention a state variable?
If you're going to use C, at least use C99.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <ctype.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    enum { SIZE = 256 };

    unsigned lengths[SIZE] = { 0 };

    int ch;
    unsigned word_length = 0;
    while ((ch = getchar()) != EOF)
    {
        if (!isalnum(ch))
        {
            if (word_length >= SIZE)
            {
                /* handle error */
            }
            else
                ++lengths[word_length];

            word_length = 0;
        }
        else
            ++word_length;
    }

    if (word_length)    /* handle case where EOF immediately follows a word */
    {
        if (word_length >= SIZE)
        {
            /* handle error */
        }
        ++lengths[word_length];
    }

    unsigned largest_count = 0;
    unsigned longest_index = 0;
    for (unsigned i = 0; i < SIZE; ++i)
    {
        if (lengths[i])
        {
            longest_index = i;

            if (largest_count < lengths[i])
                largest_count = lengths[i];
        }
    }

    const char* asterisks = "********************";
    size_t asterisks_length = strlen(asterisks);
    double ratio = ((double)asterisks_length) / longest_index;

    for (unsigned i = 1; i <= longest_index; ++i)
        printf("%3u:  %.*s\n", i, (unsigned)(ratio*lengths[i]), asterisks);
}


http://ideone.com/H8ov0Z
Hi, I`m actually reading the Kernigan & Ritchie book so why should I change tack now and go for C99 instead?

@ModShop:

Cleared up the code a little bit, this is what you were asking right

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#include <stdio.h>

int main()

{

int c, i, j, word, current_word_length;
wordn = 0;
word = 0;
state = 0;
int length [20];

  for (i=0; i<20; ++i) {
  length[i] = 0;            // initialize elements
  i = 0;
 }  

   while ((c = getchar()) != EOF  && word < 20) {
     
      if (c == ' ' || c == '\t' || c == '\n')
      
      {  
        
        current_word_length = length[i]
        ++i;                  
        ++word;
        
      }
      
      current_word_length = 0;

      if (c != ' ' && c != '\t' && c != '\n') {
        
        ++ current_word_length;                        
        ++ length[current_word_length];
       }
       
   }
       
     
   
   printf( "histogram:");
  for (i=0; i<20; ++i)     {
 printf( "%2d", i);
 for (j = 0; j < lengths[i]; ++j)
    printf("*");
    printf("\n");
    
   }
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


#include <stdio.h>

int main()

{

int c, i, j, word, length, space;
length = 0;
word = 0;
space = 0;
int length [20];

  for (i=0; i<20; ++i) {
  length[i] = 0;            // initialize elements
 }  

   while ((c = getchar()) != EOF  && word < 20) {
     
      if (c == ' ' || c == '\t' || c == '\n')
      
      { 
        space = 0;
        ++word;
        ++i; 
        i = 0;
      }
      
      

      if (c != ' ' && c != '\t' && c != '\n') 
      
      {
         if (space = 0)
          {
        
          space = 1;
          ++length[i];                     
          }
       
      }
       
     
   
   printf( "histogram:");
  for (i=0; i<20; ++i)     {
 printf( "%2d", i);
 for (j = 0; j < length[i]; ++j)
    printf("*");
    printf("\n");
    
   }
}

Not quite, but you're getting there. Here's some incomplete code to give you a better idea:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main() {
    int lengths[20];
    int currentWord = 0;
    int currentWordSize = 0;
    char c;

    while ((c = getchar())!=EOF && currentWord<20)  {
        if (c==' ' || c=='\t' || c=='\n') {
            //we've hit the end of the word. Set lengths[currentWord] to the counted word length
            //then reset the counted word length to 0 and increment the current word
        }
        else {
            //we're in a word, increment the current word length
        }
    }

    //now loop through the lengths array in the range [0,currentWord) and output
    return 0;
}
Hi ModShop,

Thank you for your interest in this issue. I`m afraid that I don`t quite get your point.
Here is something that I put together:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64


/* Warning! Not compiled or tested in any environment */



#include <stdio.h>

#define IN1
#define OUT 0
#define MAXLENGTH 15


int main()

{

int c, i, j, word, length, overlong_words;

int word_length [MAXLENGTH+1];

  for (i=0; i<MAXLENGTH; ++i) {
  word_length[i] = 0;            // initialize elements
 }  

 word = OUT;
 
 while ((c=getchar()) != EOF) {
 	
 if (c = ' ' || c = '\n' || c = '\t')
 {
   if (length <= MAX_LENGTH)	
   ++word_length[length];
   
    else 
          {   
              ++overlong_words;
              word = OUT;
          }
          
      else if (word == OUT)
      
     {
        length = 0;
        word = IN;
     	
     }
     
       ++length;
 	
 	
 }

   
   printf( "histogram:");
  for (i=0; i<[MAXLENGTH]; ++i)     {
 printf( "%2d", i);
 for (j = 0; j < length[i]; ++j)
    printf("*");
    printf("\n");
    
   }
}
Pages: 12