-
help with counting words
I have written the following code to count the number of words, uppercase/lowercase letters, punctuation, and digits. The only problem I am having is counting the last word. Any suggestions? Do I need something after the loop?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define SIZE 80
int main(void)
{
char s[SIZE];
int sl;
int p;
int QW=0;
int QUL=0;
int QLL=0;
int QP=0;
int QD=0;
printf("This program will request and store a string of characters\n");
printf("and then report:\n");
printf(" Number of Words.\n");
printf(" Number of uppercase letters.\n");
printf(" Number of lowercase letters.\n");
printf(" Number of punctuation characters.\n");
printf(" Number of digits.\n\n");
fflush(stdin); /* Flush Keyboard Buffer */
printf("On the line below, enter the string that should be analyzed:\n");
printf("\n> ");
fgets(s, SIZE, stdin);
if(s[strlen(s) - 1] == '\n')
s[strlen(s) - 1] = '\0';
sl = strlen(s);
for(p=0; p < sl; p++)
if(s[p] != '\0')
{
if(isupper(s[p]))
QUL = QUL + 1;
else if(islower(s[p]))
QLL = QLL + 1;
else if(isdigit(s[p]))
QD = QD + 1;
else if(ispunct(s[p]))
QP = QP + 1;
else if(isspace(s[p]))
QW = QW + 1;
}
printf("\nRESULTS:\n\n");
printf("Number of words: %d\n", QW);
printf("Number of uppercase letters: %d\n", QUL);
printf("Number of lowercase letters: %d\n", QLL);
printf("Number of punctuation characters: %d\n", QP);
printf("Number of digits: %d\n", QD);
fflush(stdin);
getchar();
return(0);
}
Thanks.
-
well, besides other things, you are counting words via spaces, so if user enters "standard" sentence with just one space between words and no spaces leading/trailing, you need to count spaces + 1 :)
-
well you have to add one to the word counter automatically because once it hits the \0 it doesn't do anything in the loop(count the last word) You see what I mean?
-
Read this FAQ entry, and then don't do that any more.
Also, if I were to include multiple spaces in a row, your count will be off.
Quzah.
-
ummm, I can see how that would make sense right away when you're coding it...but it's got its flaws
I've made quite a few parsers and I've gotten myself in to the mindset of trying to think of every possible outcome to any given input, heh, so let's see:
you're counting how many words there are by how many spaces there are?
flaw #1) Space counting
--Example 1:
--Based on your current algo:
---Scans the string, finds 3 spaces, counts there being 3 words. However, there's only 2!
--Suggestions:
---Scan the string, and have a flag that says whether or not you're reading a non-whitespace character, and.....errrk, hard to explain, here's a better explanation with an example:
4 words, correct?
With the current algo, it'll count there being 7 words, which is way off.
Here's what should happen in pseudocode
Code:
Run through the string, one letter at a time
if current letter isn't a space
turn on the "reading word" flag
if current letter IS a space, and the "reading word" flag is set
increment the word count
reset the "reading word" flag
and you should be able to incorporate that in to your code
flaw #2) End of line counting
--Example 1:
--Based on current algo:
---It will find there being only 1 word, which is correct, but if you do what everyone's saying above, with the just "add one" logic....that's quite flawed
What would be better is to build off of flaw #1's solution and at the end of the loop do:
Code:
if the "reading word" is set
increment the word count
and that would go at the end of the loop
basically what it does is once we hit the end, if we're still reading a word, then there must *be* a word at the end, right?
-hope that helps
-
You don't have to have a word flag:
Code:
while( *s )
{
while( *s && isspace( *s ) ) s++; /* skip all the spaces */
if( *s (&& depending on what you call a word, call an is function if you prefer ) )
word++;
while( *s && !isspace( *s ) )
{
count each letter, punctuation, number, whatever
s++;
}
}
That looks sufficient.
Quzah.
-
*nods*
that works too, good point
-
Thanks to all for the ideas!
geo_c