如果C中的循环没有正确迭代

时间:2017-08-21 19:42:13

标签: c

在C上写一个单词计数器。我计算字符串中的空格数来确定单词的数量。我猜测我的if语句有问题。有时它会计算单词的数量以及其他随机数字的数量吗?例如"我的红狗"有三个字但是"我喝朗姆酒"有一个字和"这段代码毫无意义"有三个。它为每个字符串打印字符串的长度。

以下是相关代码的一部分:

void WordCounter(char string[])
{   int counter = 1; 
    int i = 0;
    int length = strlen(string);
    printf("\nThe length of your string is %d", length);

    for( i=0;i<length;i++){

        if (string[i] == ' ')
        {
            counter+=1;
            ++i;

        }
        else

        {
            counter +=0;
            ++i;
        }
    }

    printf("There are %d words in this sentence and i is equal to: %d", counter, i);
}

5 个答案:

答案 0 :(得分:3)

for循环的i ++部分意味着我在每个循环中递增,你不应该在循环内再次执行。此外,这里没有必要你的其他人。您需要删除以下位:

for( i=0;i<length;i++) {
    if (string[i] == ' ')
    {
        counter+=1;
    }
}

答案 1 :(得分:0)

您的代码在3个不同的地方增加了i。增量只需要循环。
试试这段代码:

for( i=0;i<length;i++){
    if (string[i] == ' ')
    {
        counter++;
    }
}

答案 2 :(得分:0)

你在同一个循环中增加2次。一个在for语句中,一个在循环中。这意味着你只检查两个字符。它可以解释为什么所有对空间都不在计数中:

我把所有配对角色都放在Bolt中:

  

m y r e d d o g”:两个空格都是非配对号

     

d r n k r u m “:两个空格都是非配对数

以下是您更正的源代码:

void WordCounter(char string[]){   
int counter = 1; 
int i = 0;
int length = strlen(string);
printf("\nThe length of your string is %d", length);

for( i=0;i<length;i++){

    if (string[i] == ' ')
    {
        counter+=1;
    }
}

printf("There are %d words in this sentence and i is equal to: %d", counter, i);
}

答案 3 :(得分:0)

您发布的代码的最大问题是它不正确地增加i

for( i=0;i<length;i++){

    if (string[i] == ' ')
    {
        counter+=1;
        ++i; // here

    }
    else
    {
        counter +=0;
        ++i; // here
    }
}

您似乎尝试做的事情都不需要上面//here行。此外,整个else块是没有意义的,因为除了i之外什么都不会修改,它不应该做。因此,更正确的方法就是:

for(i=0; i<length; ++i)
{
    if (string[i] == ' ')
        ++counter;
}

每当您索引空格' '字符时,此计数器都会递增。对于一个简单的算法,这可能足以满足您的要求。

计算空格,而不是单词

您的算法确实不会对单词进行计数,它只会计算遇到的空格字符数加一。这意味着一些输入,例如下面的那些(用于记录字符串中的内容的引号,实际上不存在),将返回准确的字数:

// shoud be zero, but returns one
"" 

// should be zero, but returns four (three spaces)
"   "

// should be one, but returns five (two spaces, either side)
"  word  "

// should be two, but returns three (two spaces between)
"word  word"

etc.  

需要更强大的算法。请注意,这并不能解决所有问题,但它可以帮助您完成我们所称的“#34;单词&#34;”。也就是说,非空白字符由空白字符分隔,并可能支持到字符串的末尾。

这使用指针而不是索引。在我看来,它更容易阅读,并从索引语法中整理代码,从而放大了实际发生的事情:消耗空白,然后消耗我们称之为&#34; word&#34;的非空格。内联评论应该解释发生了什么:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int WordCounter(const char *s)
{
    int counter = 0;

    // while we haven't reached terminating nullchar
    while (*s)
    {
        // discard all whitespace until nullchar or non-whitespace found
        for (; *s && isspace((unsigned char)*s); ++s);

        // if not nullchar, we have the start of a "word"
        if (*s)
        {
            ++counter;

            // discard all text until next whitespace or nullchar
            for (; *s && !isspace((unsigned char)*s); ++s);
        }
    }

    return counter;
}

int main()
{
    const char *s1 = "There should be eight words in this string";
    printf("\"%s\"\nwords: %d\n", s1, WordCounter(s1));


    const char *s2 = "  There   should\t\t\tbe  eight\n in\n this\n string too\n ";
    printf("\"%s\"\nwords: %d\n", s2, WordCounter(s2));

    const char *s3 = "One";
    printf("\"%s\"\nwords: %d\n", s3, WordCounter(s3));

    const char *s4 = "";
    printf("\"%s\"\nwords: %d\n", s4, WordCounter(s4));

    return 0;
}

<强>输出

"There should be eight words in this string"
words: 8
"  There   should           be  eight
 in
 this
 string too
 "
words: 8
"One"
words: 1
""
words: 0

不完美;只是更好

先前的算法仍然不完美。准确地提取单个单词需要知道标点符号,潜在的连字符等。但它更接近于看起来像目标。希望你从中获得一些东西。

答案 4 :(得分:-1)

你甚至不需要i变量

counter = 0;
while(*str) 
    counter += *str++ == ' ' ? 1 : 0;
printf("There are %d spaces (not words as you may have more              spaces between words) in this sentence and length of the string is: %d", counter, length);



int isDelimeter(int ch, const char *delimiters)
{
    return strchr(delimiters, ch) != NULL;
}

const char *skipDelimiters(const char *str, char *delimiters)
{
    while (*str && isDelimeter(*str, delimiters)) str++;
    return str;
}

const char *skipWord(const char *str, char *delimiters)
{
    while (*str && !isDelimeter(*str, delimiters)) str++;
    return str;
}

const char *getWord(const char *str, char *buff, char *delimiters)
{
    while (*str && !isDelimeter(*str, delimiters)) *buff++ = *str++;
    *buff = 0;
    return str;
}

int countWords(const char *str, char *delimiters)
{
    int count = 0;
    while (*str)
    {
        str = skipDelimiters(str, delimiters);
        if (*str) count++;
        str = skipWord(str, delimiters);
    }
    return count;
}

int printWords(const char *str, char *delimiters)
{
    char word[MAXWORDLENGTH];
    int count = 0;
    while (*str)
    {
        str = skipDelimiters(str, delimiters);
        if (*str)
        {
            count++;
            str = getWord(str, word, delimiters);
            printf("%d%s word is %s\n", count, count == 1 ? "st" : count == 2 ? "nd" : count == 3 ? "rd" : "th", word); 
        }
    }
    return count;
}