我想创建一个函数,它使一个数组充满字符串并计算单词。我不认为我在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);
}
}
答案 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
循环,它们容易出错,而且这个错误是经典错误。以下是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);
}