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

时间:2017-09-03 21:33:20

标签: c string multidimensional-array while-loop escaping

我想创建一个函数,它使一个数组充满字符串并计算单词。我不认为我在pic中的代码是错误的。每次出现空白时都会计算。但是当'\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);
    }
}

4 个答案:

答案 0 :(得分:2)

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

#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()函数执行两项任务 - 并且只应该执行一项,将另一项委派给另一项功能。它都计算单个字符串中的单词并打印相关信息。我将单词count计算到一个单独的函数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.    ]

显然,如果您愿意,可以使用isblank()中的isspace()<ctype.h>宏(函数)来优化空间测试,或者在其他地方定义word和not-word之间的边界方法。然而,基本概念是可靠的,包括相当不正常的空白和单词序列。

如果你真的想要一个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脚本无法正确处理该字符串之类的参数。

答案 1 :(得分:1)

内部循环遇到'\0'字符后立即终止。在遇到'\0'时,它唯一会计算一些事情的时间w[i][0] == '\0'对于某些i。对于某些'\0',位置w[i][j]上的任何j > 0都不会导致counter增加,因为该循环将事先终止。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

以下是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);
}