繁体   English   中英

c的while循环中的'\\ 0'字符

[英]'\0' character in a while loop at c

我想做一个函数,该函数需要一个充满字符串的数组并计算单词数。 我不认为照片中的代码是错误的。 每次出现空白时,都会对其进行计数。 但是,当出现'\\0'字符时, while循环不会执行任何操作。 是我不知道的事吗?

int Number(char w[][20]) {
    int i, counter, j;
    counter = 0;
    for (i = 0; i < 4; i++) {
        j = 0;
        do {
            if ((w[i][j] == '\0') || (w[i][j] == ' '))
                ++counter;
            j++;
        } while (w[i][j] != '\0');
        printf("counter=%d\n", counter);
    }
}

这是您的代码的工作版本和测试程序。

#include <stdbool.h>
#include <stdio.h>

static int wc(const char *str)
{
    int count = 0;
    bool inword = false;

    char c;
    while ((c = *str++) != '\0')
    {
        if (c == ' ')
            inword = false;
        else
        {
            if (inword == false)
                count++;
            inword = true;
        }
    }
    return count;
}

static void Number(const char *tests[], int num_tests)
{
    for (int i = 0; i < num_tests; i++)
        printf("%d: [%s]\n", wc(tests[i]), tests[i]);
}

int main(void)
{
    const char *tests[] =
    {
        "",
        " ",
        "  ",
        "a",
        "a b",
        " a b ",
        "  ab  cd  ",
        "The quick brown  fox jumps  over   the  lazy     dog.",
        "      The quick brown  fox jumps  over   the  lazy     dog.    ",
    };
    enum { NUM_TESTS = sizeof(tests) / sizeof(tests[0]) };
    Number(tests, NUM_TESTS);
    return 0;
}

请注意,您的Number()函数完成两项工作-只能完成一项工作,而将另一项委派给单独的函数。 它既可以计算单个字符串中的单词,也可以打印相关信息。 我将单词计数委托给一个单独的函数wc() ,这大大简化了Number()的代码-几乎达到了不需要该函数的地步。 还要注意,我的Number()版本被告知正在处理的数组的条目数,而不是依赖于像4这样的幻数。 请注意,我的代码输出允许您检查其准确性。 简单地打印输出编号并不能使您如此轻松地检查准确性。 您必须查看代码以了解数字的含义。 请注意,您的Number()函数已定义为返回一个int但实际上并未这样做。 此版本定义为不返回任何内容,也不返回任何内容。

该代码的输出为:

0: []
0: [ ]
0: [  ]
1: [a]
2: [a b]
2: [ a b ]
2: [  ab  cd  ]
9: [The quick brown  fox jumps  over   the  lazy     dog.]
9: [      The quick brown  fox jumps  over   the  lazy     dog.    ]

显然,如果愿意,可以使用<ctype.h>isblank()isspace()宏(函数)优化空间测试,或以其他方式定义单词和非单词之间的边界。 但是,基本概念在空白和单词的相当不正确的序列中是可靠的。

如果您确实想要2D字符数组,则编写代码以使用该数组并不难,尽管必须将“懒狗”字符串简化为完全适合char data[][20] 基本思想保持不变wc()函数不变。

#include <stdbool.h>
#include <stdio.h>

static int wc(const char *str)
{
    int count = 0;
    bool inword = false;

    char c;
    while ((c = *str++) != '\0')
    {
        if (c == ' ')
            inword = false;
        else
        {
            if (inword == false)
                count++;
            inword = true;
        }
    }
    return count;
}

static void Number(const char tests[][20], int num_tests)
{
    for (int i = 0; i < num_tests; i++)
        printf("%d: [%s]\n", wc(tests[i]), tests[i]);
}

int main(void)
{
    const char tests[][20] =
    {
        "",
        " ",
        "  ",
        "a",
        "a b",
        " a b ",
        "  ab  cd  ",
        "The quick brown fox",
        "  jumps   over     ",
        "  the  lazy  dog   ",
    };
    enum { NUM_TESTS = sizeof(tests) / sizeof(tests[0]) };
    Number(tests, NUM_TESTS);
    return 0;
}

输出:

0: []
0: [ ]
0: [  ]
1: [a]
2: [a b]
2: [ a b ]
2: [  ab  cd  ]
4: [The quick brown fox]
2: [  jumps   over     ]
3: [  the  lazy  dog   ]

" ab cd "示例(开头,中间和结尾处有双空格)之类的测试通常是用于处理极端情况的非常好的测试-在更多情况下,不仅仅是单词计数。 例如,许多Shell脚本将无法正确处理类似该字符串的参数。

 - The first principle of programming is: divide and conquer
 - The second is: use  a loop to iterate
So:

unsigned count_words(char*str)
{
unsigned len, words;

for(len=words=0; *str; str++){
        if(*str == ' ') if(len) {words++; len=0;}
        else len += 1;
        }

if (len) {words++; }
return words;
}

现在,为您的任何字符串调用此函数,添加结果。

您的代码中存在一些问题:

  • 如果一行没有字符(以'\\0'开头),则在测试字符串结尾之前先递增j 不要使用do / while循环,因为它们很容易出错,而这个错误是经典的错误。
  • 您只计算空格数:这与单词数不同,因为2个单词之间或行首或结尾处可能有多个空格,等等。您应该计算从空格到非空格的过渡数-space,从太空开始。

这是2D数组的简单实现:

int Number(char w[][20]) {
    int i, j, counter = 0;
    for (i = 0; i < 4; i++) {
        char c, last = ' ';
        for (j = 0; (c = w[i][j]) != '\0'; j++) {
            if (last == ' ' && c != ' ')
                counter++;
            last = c;
        }
    }
    printf("counter=%d\n", counter);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM