2

I'm fairly new to coding. I'm having trouble with my "CountSentences" function. I compare the string to "." , "?" , and ! to count a sentence. It only adds one to the sentence counter no matter how many of the punctuation marks I have in the string. Am I using strcmp wrong to get my desired result and is there another way I can approach this?

 #include<cs50.h> #include<ctype.h> #include<string.h> #include<math.h> //function for letter count int count_letters(string s) { int numberofLetters = 0; // counter //loop as long as string length for(int i = 0, n = strlen(s); i < n; i++) { //if character is alphanumeric if(isalnum(s[i]) != 0) { numberofLetters++; //increase counter }; }; return numberofLetters; //return new counter number }; //function for word count int count_Words(string w) { int numberofWords = 0;//counter for words declared int i = 0; // counter for character in string if(w == NULL) // if nothing { return numberofWords; // return Wordcount of 0 }; bool spaces = true; //truth value for space //if character is not null terminating character while(w[i] != '\0') { if(isblank(w[i]) != 0) //if character is blank { spaces = true; //its a space } else if(spaces) //if no more space and a letter is present add to words { numberofWords++; //add to number of words counter spaces = false; }; i++;// increase chracter count in string w }; return numberofWords; //return total word counter }; //function to count sentences int count_Sentences(string l) { //variable counter for marks int countMarks = 0; //loop iteration using the number of characters in string for(int i = 0, n = strlen(l); i < n; i++) { //check if character is ?, . , or ! if(strcmp(&l[i], "!") == 0 || strcmp(&l[i], ".") == 0 || strcmp(l, "?") == 0) { countMarks++;// sentence counted }; }; // return the total number of marks return countMarks; }; int main (void) { string text = get_string ("Text: "); //to check the functions bug checker printf("Number of letters: %i\n", count_letters(text)); printf("Number of words: %i\n", count_Words(text)); printf("Number of sentences: %i\n", count_Sentences(text)); //Coleman Liau Index int grade = round(0.0588 * (100 * (count_letters(text)) / (count_Words(text))) - 0.296 * (100 *(count_Sentences(text)) / (count_Words(text))) - 15.8 ); if(grade <= 1) { printf("Before Grade 1\n"); } else if(grade < 16) { printf("Grade %i\n", grade); } else { printf("Grade 16+\n"); }; }; 
7
  • 6
    Your code is comparing all the rest of the input with a one-char string. I suggest if(l[i] == '!') etc. Aside: it's ill-advised to use l (the letter ELL) as variable name. It is too easily confused with 1 (the digit ONE) making the code hard to read, and open to mistakes. Commented Jun 25, 2020 at 18:10
  • 1
    You might like to know about the function family ispunct() and isspace() and isalpha() and so on, declared in ctype.h. Commented Jun 25, 2020 at 18:15
  • regarding: ` }; };` do not place a semicolon ; after a closing brace } Commented Jun 26, 2020 at 4:45
  • the posted code is missing the statement: #include <stdio.h> for the printf() and similar functions Commented Jun 26, 2020 at 4:48
  • 1
    regarding: if(strcmp(&l[i], "!") == 0 || strcmp(&l[i], ".") == 0 || strcmp(l, "?") == 0) This will NOT work because a single char from l[] is not a string. Suggest: if( l[i] == '!' || l[i] == '.' || i[i] == '?' ) Notice the use of single quotes rather than double quotes so comparing a character rather than a string. Notice the use of appropriate horizontal spacing for readability. Commented Jun 26, 2020 at 5:03

2 Answers 2

3
 if(strcmp(&l[i], "!") == 0 || strcmp(&l[i], ".") == 0 || strcmp(l, "?") == 0) 

strcmp compares two strings. In C, our "string" is essentially "the char-sized data starting at the place this pointer points to, and continuing until a null terminator". The cs50 library does not change this and does not give you a real string type; it only provides a typedef and some helper functions for reading input. (It also, sadly, does not and realistically cannot give you a real text character type, which char also is not; but that is beyond the scope of this answer.)

&l[i] is a pointer into the middle of the l string, starting at offset i. When that pointer is used by strcmp, it will treat the "string" as everything from that character to the end of the original string - because that's where the null terminator is. It will, in particular, not treat the single l[i] char as a separate string, in general, because the next char is in general not a null terminator. So,

It only adds one to the sentence counter no matter how many of the punctuation marks I have in the string.

In fact, it only even adds one because your string ends with one of those marks.

To compare individual chars, don't use strcmp. It is not intended nor fit for the purpose. A char is a single entity, so it can be compared just fine with ==. You just need to have something appropriate on both sides of the comparison.

Recall, in C single quotes are used for char literals, and indexing into the char array (equivalently, "indexing" into a char pointer, which performs the equivalent pointer arithmetic) gives you a char. Thus:

if (l[i] == '!' || l[i] == '.' || l[i] == '?') 
Sign up to request clarification or add additional context in comments.

2 Comments

Aside: "C single quotes are used for char literals" --> In C, '!' is a character constant. C has 2 literals defined: string and compound, but not char literal. Both of which can have their address taken, unlike a constant. In C, '!' is type int.
strchr is MUCH bore suitable
2

You indeed need to see if the one character l[i] is any of ., ? or !. To do that, you can test if that is equal to any of these character constants, i.e. l[i] == '!' || l[i] == '.' || l[i] == '?'

Or you can use the function strchr that will look for a given character in a given string and return a pointer to that character, or a null pointer if the character is not found. A null pointer will be considered as falsy in if, and and a non-null pointer truthy. So we can look for l[i] in the string ".?!":

if (strchr(".?!", l[i])) { ... } 

1 Comment

This works well when l[i] != 0, which it cannot be due to prior n = strlen(l); i < n; as strchr(".?!", 0) is not-NULL too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.