如何使用“。”,“?”,“!”计算C中句子的数量?

How do I count the number of sentences in C using ".", "?", "!"?

我对编码还很陌生。我的“CountSentences”函数有问题。我将字符串与“.”进行比较,“?” , 和 !算一个句子。无论我在字符串中有多少个标点符号,它只会向句子计数器添加一个。我是否错误地使用了 strcmp 来获得我想要的结果,还有其他方法可以解决这个问题吗?

#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] != '[=10=]')
    {


        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");
    };
};
    if(strcmp(&l[i], "!") == 0  || strcmp(&l[i], ".") == 0  ||  strcmp(l, "?") == 0)

strcmp 比较两个 字符串 。在 C 语言中,我们的“字符串”本质上是“字符大小的数据,从该指针指向的位置开始,一直持续到空终止符”。 cs50 库不会改变这一点,也不会给你一个真正的字符串类型;它只提供一个 typedef 和一些用于读取输入的辅助函数。 (不幸的是,它也没有并且实际上不能给你一个真正的文本字符类型,char也是不是;但是这超出了这个答案的范围。)

&l[i] 是指向 l 字符串中间的 指针 ,从偏移量 i 开始。当 strcmp 使用该指针时,它会将“字符串”视为 从该字符到原始字符串末尾的所有内容 - 因为那是空终止符所在的位置。特别是,它通常 not 将单个 l[i] 字符视为单独的字符串,因为下一个字符通常不是空终止符。所以,

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

事实上,它甚至只加一个,因为您的字符串以这些标记之一结尾。

要比较单个字符,请不要使用 strcmp。它不适合也不适合该目的。 char 是一个单独的实体,因此可以很好地与 == 进行比较。你只需要在比较的两边都有合适的东西。

回想一下,在 C 中,单引号用于 char 文字,并且索引到 char 数组(等效地,“索引”到 char 指针,执行等效的指针算术)给你一个 char。因此:

if (l[i] == '!' || l[i] == '.' || l[i] == '?')

您确实需要查看一个字符l[i]是否是.?!中的任何一个。为此,您可以测试它是否等于这些字符常量中的任何一个,即 l[i] == '!' || l[i] == '.' || l[i] == '?'

或者您可以使用函数 strchr 查找给定字符串中的给定字符,并 return 指向该字符的指针,如果找不到该字符,则为空指针。在 if 中,空指针将被视为虚假,非空指针将被视为真实。所以我们可以在字符串 ".?!":

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