2017-09-03 36 views
1

我想要一个函数,它需要一个数组充满字符串和计数单词。我不认为我的代码在图片中是错误的。每次出现空白时都会被计数。但是当'\0'字符出现时,while循环不会执行任何操作。是我不知道的东西?' 0'字符在一个while循环在c

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); 
    } 
} 
+2

如果字符串是 “空”,即,仅包括' “\ 0”''然后\ 0'将被计数,但否则'do .. while()'循环条件将'\ 0'排除在考虑之外。我建议使用'while(){...}'循环。想一想“何时出现'\ 0'字符”。它不是* C字符串中的字符*,而是它的结束标记。 –

+0

当它到达\ 0字符时,循环停止,那么为什么你认为它会被计算? – immibis

+0

while循环不起作用。如果我没有在一行中放入任何二维数组,那么这一段时间根本不会被执行......尽管在我写论坛之前,我仍尝试过。 –

回答

0

有在你的代码的一些问题:

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

这里是您的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); 
} 
+0

你是对的。在一个完整的程序中是必要的。你的方法比我的更聪明,我会重写我的函数。我不知道为什么这个该死的转义整数'\ 0'结束了我的操作...while循环结束之前,但我会有一个更好,更多的逻辑程序。谢谢你的时间。 –

1

只要遇到'\0'字符,您的内循环就会终止。唯一一次遇到'\0'时会计数的东西是当w[i][0] == '\0'i时。对于某些j > 0,位置w[i][j]上的任何将不会导致counter增加,因为循环将被预先终止。

+0

你确定吗?它看起来好像它计算空字节,因为在尾部'while'之前,在循环体内出现null或空白测试。 –

+0

我确定。循环的主体也增加'j'。这意味着除非''\ 0''是'w [i]'的第一个字符,循环终止。举一个具体的例子,假设'w [0]'是字符串'“ab \ 0cd”'(我们只是在C中避开它,字符串被NUL终止)。我们从'j == 0'开始,进入循环,并比较'if'中的'w [0] [0]'。现在我们增加'j',并继续循环,因为w [0] [1]'不是'''0'。在第二次迭代期间,我们检查'if'中的'w [0] [1]'并增加'j'。现在,门卫检查'w'[0] [2]'到'\ 0'',终止循环。 – Abigail

+0

注意''ab \ 0cd“'不是一个字符串;一个字符串停在第一个空字节处; –

0
- 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; 
} 

现在,调用这个函数任何你的字符串,加入的结果。

1

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

#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; 
} 

请注意,您​​函数完成两项工作 - 并且应该只做一,委托对方一个单独的函数。它既计算单个字符串中的单词并打印相关信息。我将计数单词委托给单独的函数wc(),这极大地简化了​​中的代码 - 几乎不需要该函数。还请注意,我的版本​​被告知它正在处理的数组的条目数量,而不是依赖像4这样的幻数。请注意,我的代码输出允许您检查它的准确性。只需打印输出号码不会让您轻松检查准确性;您必须查看代码才能了解数字的含义。请注意,您的​​函数被定义为返回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>细化空间测试,如果你愿意,也可以定义字和不可─之间的边界用其他方式说话。尽管如此,基本的概念是可靠的,可以跨越空白和文字的相当不正确的序列。

如果你真的想要一个二维数组的字符,编写代码来处理这个问题并不难,尽管'懒狗'字符串将不得不简化为适合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脚本不会正确处理像那个字符串这样的参数。

+0

你是绝对正确的,事实上我的功能哲学调整''和词必须改变。 –