首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >初学者C:阅读时代

初学者C:阅读时代
EN

Stack Overflow用户
提问于 2020-08-24 17:32:08
回答 3查看 89关注 0票数 1

我正在用C语言学习初级编程,我正在做一个挑战来确定不同句子的阅读年龄。这是通过确定字符串中句子的数量来实现的。我有一些代码可以完成我的第一个非常基本的步骤,但是它并不像预期的那样工作。

我认为这是因为我对strlen函数等的了解还不够。

我不想欺骗答案,因为我喜欢解决问题的成就感。但是,如果有可能的话,是否有可能在正确的方向上得到温和的推动?

代码语言:javascript
复制
char sentence[] = "One fish. Two fish. Red fish. Blue fish.";

int main(void)
{
    int sentence_count = 0;
    int word_count = 0;
    int i;
    int length = strlen(sentence);

    for (i = 0; i == strlen(sentence); i++)  //need to somehow go through a string one char at a time until the end.
    {
        if (sentence[i] == '.' || sentence[i] == '!' || sentence[i] == ';' || sentence[i] == '?')
        {
            return sentence_count ++;
        }
        if (sentence[i] == '\0')
        {
            return word_count ++;
        }
    }
    printf("There are %i in %i sentences.\n", word_count, sentence_count);
    printf("%i\n", length);
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-24 17:36:28

第一个问题-

代码语言:javascript
复制
for (i = 0; i == strlen(sentence); i++)

这种状态应该是-

代码语言:javascript
复制
for (i = 0; i < strlen(sentence); i++)

在您的例子中,它将在第一次迭代本身中终止。但是,在到达索引- strlen(sentence)之前,需要循环。

请记住,for循环具有语法- for(initialisation; condition; increment/decrement)只会在条件计算为true之前运行。因此,您需要计算为true的条件,直到遍历了由上面提到的第二行代码完成的整个字符串。

另一种更好的办法是-

代码语言:javascript
复制
for (i = 0; sentence[i] != '\0'; i++)

这意味着循环将运行,直到遇到以空结尾的字符。

第二个问题-

代码语言:javascript
复制
return sentence_count ++;
.
.
return word_count ++;

在这里,您不需要在上面的两个语句之前添加return关键字。return将直接退出您的程序。简单地编写sentence_count++word_count++是正确的。

第三个问题-

代码语言:javascript
复制
sentence[i] == '\0'

这一说法不太符合我们正在努力实现的逻辑。相反,语句必须检查字符是否为空格,然后增加单词计数-

代码语言:javascript
复制
if (sentence[i] == ' ')
{
    return word_count ++;
}
票数 2
EN

Stack Overflow用户

发布于 2020-08-24 17:37:06

您的for循环条件是主要问题;for (i = 0; i == strlen(sentence); i++)读取为“在输入时,将i设置为0,每次i等于sentence的长度时输入主体,在每个循环的末尾增加i”。但这意味着除非sentence是空字符串(有strlen of 0),否则循环永远不会运行。您希望测试i < strlen(sentence) (或者为了避免一遍又一遍地重新计算长度,请使用您已经计算过的lengthi < length)。

您还需要删除您的return;函数应该计数,并且正如所写的那样,它在找到任何目标字符时就会return 0,而不以任何方式使用递增的值。将一个return 0;放在main的末尾,以表示成功退出(可以选择包含stdlib.h,这样您就可以使用return EXIT_SUCCESS;来避免神奇的数字,但这是相同的行为)。

票数 1
EN

Stack Overflow用户

发布于 2020-08-24 19:58:27

其他答复中的信息已经被涵盖,这里有几个其他建议供您考虑。

strlen()循环中删除函数调用,例如for(;;)。您已经通过以下方法获得了长度:

代码语言:javascript
复制
int length = strlen(sentence);  

现在,只需在for循环中使用它:

代码语言:javascript
复制
 for(i = 0; i < length ; i++)//includes replacement of == with <

封装代码的工作部分,在本例中是单词和句子的计数。以下内容使用了不同的方法,但想法相同:

代码语言:javascript
复制
//includes deliminators for common end-of-sentence punctuation:
int count_sentences(const char *buf)
{
    const char *delim = {".?!"};//add additional 'end-of-sentence' punctuation as needed.
    char *tok = NULL;
    int count = 0;
    
    char *dup = strdup(buf);//preserve original input buffer
    if(dup)
    {
        tok = strtok(dup, delim);
        while(tok)
        {
            count++;
            tok = strtok(NULL, delim);
        }
        free(dup);
    }
    return count;
}

还有一个想法,这超出了原始代码的范围,但在实践中非常有用,那就是删除缓冲区中可能不是句子一部分的任何部分,即引导或尾随空间。在您的示例中,您在字符串文本中严格定义了句子的测试用例:

代码语言:javascript
复制
char sentence[] = "One fish. Two fish. Red fish. Blue fish.";  

这并不是不正确的,但是在某个时候,您的代码会发生什么情况呢?您的代码应该使用打包得不那么整齐的字符串缓冲区?例如,在要处理的缓冲区中引导或尾随空白字符?

代码语言:javascript
复制
"\n\n\tOne fish. Two fish. Red fish. Blue fish.\f"

在获取之前,从缓冲区中删除未知和不需要的内容可以简化代码的工作,在这种情况下可以计算句子。下面是一个简单的例子,说明如何做到这一点。

代码语言:javascript
复制
//prototype:
char *new = clear_leading_trailing_whitespace(sentence);

char * clear_end_space(const char *buf)
{
    char *new = buf;
    //clear leading whitespace
    while (isspace(*new))
    {
        new++;
    }
    //clar trailing whitespace
    int len = strlen(new);
    while(isspace(*(new + len-1))) 
    {
        len--;
    }
    
    *(new + len) = 0;
            
    return buf;
}

接下来,下面的代码段打算计算单词:

代码语言:javascript
复制
if (sentence[i] == '\0')
{
    return word_count ++;
}

但是在初始化为0之后,当看到null终止符\0一次时,word_count只增加一次。单词计数通常指缓冲区中非语句终止字符和非空白空间字符之间的空格数。或者换句话说,跟踪有多少簇的非空白。以下是这样做的一种方法:

代码语言:javascript
复制
void countwords(const char *text, *count)
{
    bool reading_word = false; // Flag
    int words = 0;
    for(int i=0; i<strlen(text); i++) 
    {
        if(isspace(text[i])) {
            reading_word = false;
        }
        else if(isalpha(text[i])) {
            if(!reading_word) {
                reading_word = true;
                words++;
            }
        }
    }
    *count = words;
} 

这样的函数可以用来极大地简化主函数的内容:

代码语言:javascript
复制
char sentence[] = "One fish. Two fish. Red fish. Blue fish.";

int main(void) 
{
    int sentence_count = 0;
    int word_count = 0;

    char *new = clear_leading_trailing_whitespace(sentence);
    countwords(new, &word_count);
    sentence_count =  count_sentences(new);
    ...
    printf("There are %d words in %d sentences.\n", word_count, sentence_count);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63565956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档