1
#include <stdio.h>

int main (void)
{
int n;

printf("Give the number of words you want to input.");
scanf("%d",&n);

int letters[n],i,j,count,key,k;
char str[100];
 //Scans each word, counts it's letters and stores it in the next available 
 //position in "letters" array.
 for (i=0;i<n;i++)
    {
        j=0;
        printf("Give the next word.");
        do{
            str[j] = getchar();
            j++;
        }while (str[j-1]!='\n');
        str[j-1] = '\0';

        letters[i] = j;
    }

//Compacts the data by figuring out which cells have the same number of letters 
for (i=0;i<n;i++)
    {
        key = letters[i];
        count = 0;
        for (j=i+1;j<=n;j++)
            {
                if (key==letters[j])
                    {   
                        count += 1;
                        letters[j] = 0;
                    }
            }
        letters[i] = count;
    }

//creates a histogram
i=0;
do{
    printf("%d|",i);
    for (j=1;j<=letters[i];j++)
    {
        printf("*");
    }
    printf("\n");
    i++;
}while ((i<=n));

return 0;

}

I understand that getchar(); reads, the first enter (\n) , user hits, to give the amount of words he wants to input, and thus expects one less word.

Also, I get an infite loop for some reason at the end. Any help and ideas would be appreciated. Thanks in advance.

abelenky
  • 63,815
  • 23
  • 109
  • 159
Mechanic45
  • 173
  • 1
  • 6
  • 16
  • 3
    Your code is saving directly into characters, which loses information about EOF, which you are not testing for anyway. That's the sort of thing that leads to trouble. Remember: `getchar()` returns an `int` which is either the value of a `char` (treated as unsigned) or a negative value (conventionally -1) indicating EOF. That's one value more than can fit into a `char`, hence the return type is `int`. I've not looked at what else is wrong. – Jonathan Leffler Jan 21 '14 at 21:13

3 Answers3

0

Wouldn't it be easier to update the letter count in the first loop?

memset(letters, 0, n);
for (i=0;i<n;i++)
{
    char* s = str;
    int j=0;
    printf("Give the next word.");
    do{
        *s = getchar();
        ++j;
    }while (*(s++)!='\n');
    s[-1] = '\0';

    letters[j-1]++;
}

As a result the second loop will be unnecessary.

bb94
  • 1,294
  • 1
  • 11
  • 24
  • I believe this is wrong: s[-1]. Other than that I dont really understand why it's diferent to what i did and why it renders the second loop uselless. – Mechanic45 Jan 21 '14 at 21:28
  • *s = '\0' is probably what you meant? (s[-1] has a negative array index, which is not allowed) – ryyker Jan 21 '14 at 21:38
  • @Mechanic45: Studying other people's code and trying to understand how it works and _why_ it works, will make you a better programmer. Simply believing it is wrong, will not. – Ruud Helderman Jan 21 '14 at 22:23
  • s will be one byte after the newline character, and negative indices are allowed, as far as I know. – bb94 Jan 22 '14 at 02:51
0

Change the first block of your code to look like this:
(test the output of getchar, and continues only if not EOF)

for (i=0;i<n;i++)
{
    j=0;
    printf("Give the next word.");
    do{
        a = getchar();
        if(a >= 0) 
        {
            str[j] = a;
            j++;
        }
        else break;
    }while (str[j-1]!='\n');
    str[j-1] = '\0';

    letters[i] = j;
}

But regarding your question: How can I replace getchar();? Have you considered using scanf()?

EDIT
Here is a simple example of using scanf() and printf() to prompt for input and then display input. It will allow user to input entire words or sentences (up to 80 characters) until 'q' is entered. Not exactly what you are doing, but you should be able to adapt it to your code... (run this)

int main(void)
{
    char buf[80]={""};
    while(  strcmp(buf, "q") != 0)  //enter a 'q' to quit
    {
        buf[0]=0;
        printf("enter string:\n");
        scanf("%s", buf);
        printf("%s\n", buf);
    }

}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • It didn't help. I changed it. Then ran it. It got the first printf right. then I gave number 5. then it printed "Give the next word.Give the next word." and then accepted only 4 more words, instead of 5 i was expecting it to. and after i inputed the 4th word it started printing "*" all over the place. – Mechanic45 Jan 21 '14 at 21:42
  • How can I use scanf() in this occassion, since I want the user to be able to type in whole words? – Mechanic45 Jan 21 '14 at 21:46
  • Okay, I will edit my answer using printf and scanf combination... (`scanf()` is perfect for typing in whole words) – ryyker Jan 21 '14 at 21:54
  • ok i adapted what you've proposed, but instead of 'q' (supposing 'q' could be a "valid" word for the user to put in) how can i make it stop when user hits esc for example? – Mechanic45 Jan 21 '14 at 22:26
  • Check on EOF; see http://stackoverflow.com/questions/1782080/what-is-eof-in-the-c-programming-language – Ruud Helderman Jan 21 '14 at 22:38
  • @Mechanic45 - Yes, you can replace 'q' with any character or string you want to. Completely arbitrary. Play with declaring buf as a char * also. Then use [mc]alloc()/free() for memory allocation/de-allocation. Removes limitations on string size. – ryyker Jan 22 '14 at 00:04
0

The following two lines have the wrong end condition; should be <n, not <=n. Currently they retrieve an uninitialized array element. Since you declared str as a local variable, that element is typically populated with garbage, i.e. a very big random number. That might explain why it takes extreme long (but possibly not forever) for the last loop to finish.

for (j=i+1;j<=n;j++)

}while ((i<=n));

Also, I assume line n of the histogram should contain the number of words that have n letters? That's not what you're doing right now.

letters[i] = count;

That line should have been:

letters[key] = count;

But to make that work, you should not overwrite the same array letters; you must declare a new array for your histogram, otherwise the second loop will destroy its own input.

By the way, str seems totally redundant. Is it there for debugging purposes?

Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45
  • about For and while you are right. about the histogram, it's supposed to display how many times a word of n letters is given with stars (*). there is no connection between the number of letters and the number of the histogram's lines. – Mechanic45 Jan 21 '14 at 21:55
  • @Mechanic45: I was talking about the _line number_, not the number of lines. Oh, but now that you mention it: there is something wrong with the number of lines too. But don't worry, now that the infinite loop is out of the way, you'll find out soon enough. A word of advice: start learning to use a debugger, it will help you get a grip of your own program. – Ruud Helderman Jan 21 '14 at 22:08
  • Uhm..indeed i meant: "...the number of letters and the number of the histogram's indivindual line." (not the total amount of lines) thanks for the advice. – Mechanic45 Jan 21 '14 at 22:30