计算C中字符串数组中的字符数

时间:2017-02-15 21:48:00

标签: c arrays

我正在尝试计算总字符数,不包括空格,(我相信)是一个指向字符串数组的指针,名为myArray。

我正在努力找出问题所在。任何帮助将不胜感激!

char *myArray[1000] = {"Oh! ", "Hello ", "world."};

int count = 0, x;

for (x = 1; x <= 1000; ++x) {
    count += strlen(myArray[x]);
}

printf(count);

期望的输出:

14

4 个答案:

答案 0 :(得分:6)

Yuu可以使用ctype.h中的标准函数来识别字符类。例如,使用issspace()可以查找字符是否为空格,如果是,则可以忽略它。

您正在将索引从1循环到1000. C中的索引从0开始并上升到N-1。此外,你只包含3个指针; rest只是NULL(隐式零初始化)。

另一个问题是您在没有格式说明符的情况下打印countcountint,您需要使用%d作为格式说明符。但是,您可以使用size_t作为类型字符串函数返回,以及可以容纳最大对象的类型。

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

int main(void)
{

char *myArray[] = {"Oh! ", "Hello ", "world."};

size_t count = 0, x, y;

for (x = 0; x < sizeof(myArray)/sizeof(myArray[0]); x++) {
    for (y = 0; myArray[x][y]; y++) {
        count += (isspace((unsigned char)myArray[x][y]) == 0);
    }
}

printf("Total chars: %zu\n", count);
}

答案 1 :(得分:4)

此代码有一堆警告。不幸的是,大多数C编译器默认情况下不会发出警告。使用-Wall打开了最常见的警告,但莫名其妙地并非全部警告。

至少告诉您,您错误地使用了printf

test.c:13:12: warning: incompatible integer to pointer conversion passing 'int' to parameter of type
      'const char *' [-Wint-conversion]
    printf(count);
           ^~~~~

printf采用格式字符串,告诉它变成字符串的东西的类型。

printf("%d\n", count);

下一个问题就是循环。

for (x = 1; x <= 1000; ++x) {

从1到1000计数。但是C中的数组从0开始。对于1000个元素数组,你想要从0到999,否则你将错过第一个元素,然后走出结束阵列。

for (x = 0; x < 1000; ++x) {

虽然myArray已经在堆栈上分配了内存,并且其前几个元素已经设置为常量字符串,但之后的所有内容都将为NULL(如果它被分配了malloc,它们将被填充用垃圾)。由于您正在迭代所有元素,因此您将空指针传递给导致段错误的strlen。你必须在第一个空值处停止。将空指针放在指针数组的末尾是了解何时停止的好方法。

最后,由于myArray充满了指向常量字符串的指针,因此您应该将其声明为const char的指针列表。这会使这个警告变得安静,告诉你可能正试图修改常量字符串。

test.c:5:28: warning: initializing 'char *' with an expression of type 'const char [5]' discards
      qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
    char *myArray[1000] = {"Oh! ", "Hello ", "world.", NULL};

全部放在一起......

#include <stdio.h>
#include <string.h>

int main() {
    const char *myArray[1000] = {"Oh! ", "Hello ", "world."};

    int count = 0, x;

    for (x = 0; myArray[x] != NULL; ++x) {
        count += strlen(myArray[x]);
    }

    printf("%d\n", count);
}

现在我们已经完成了基本循环,我们可以将strlen替换为在跳过空格时对字符进行计数的内容。

ctype.h有许多功能可以找出类型 c haracter的内容。我们可以使用isspace来判断一个字符是否为空格。但我们必须编写自己的函数来遍历字符串并检查所有字符。

有许多循环字符串的方法。我们可以得到长度并迭代。

size_t len = strlen(string);
for( int i = 0; i < len; i++ ) {
    ...
}

但是C并不存储字符串的长度。 strlen必须在字符串中执行自己的循环,直到它看到一个空字节为止,所以上面的内容实际上是循环遍历字符串两次。我们可以做得更好,并通过自己查找空字节来迭代。

同样,我们可以使用正常的for循环和循环,直到我们看到一个空字节。

for( int i = 0; string[i] != '\0'; i++ ) {
    ...
}

但我们甚至不需要i。相反,我们可以直接递增string,更改字符串开头的位置,并始终查看string[0]

int count_chars_without_spaces( const char *string ) {
    int count = 0;

    for( ; string[0] != '\0'; string++ ) {
        if( !isspace(string[0]) ) {
            count++;
        }
    }

    return count;
}

这很好,因为string是该特定函数的本地变量。我们可以在不改变字符串的情况下进行更改。

所以请将其插入而不是strlen并且你很好!

答案 2 :(得分:3)

这个问题存在一些问题,其中大部分都是Schwern的回答。我会解决一些问题,包括原始问题中关于不计算空格的要点:

  1. 重申一下,C数组是0索引的。

  2. 您可能想要一个无界循环,这样您就可以在不更改代码的情况下向数组中添加更多元素(并且数字1000会使解决方案回旋)。此时,x的最大值变为sizeof(myArray) / sizeof(myArray[0]),即元素数量。您还可以让编译器通过从1000的定义中删除myArray来决定制作数组的大小:char *myArray[] = {"Oh! ", "Hello ", "world."};

  3. 顶级循环计算完整字符串的字符串长度,但您只需要非空格字符。有很多方法可以做到这一点,但最直接的方法是在嵌套循环中计算非空格字符。

  4. 鉴于这些,下面的代码获得了所需的输出:

    #include<stdio.h>
    #include<string.h>
    
    int main() {
      char *myArray[] = {"Oh! ", "Hello ", "world."};
      int count = 0;
      int arrayLength = sizeof(myArray) / sizeof(myArray[0]);
    
      for (int x = 0; x < arrayLength; x++) {
        int stringLength = strlen(myArray[x]);
    
        for (int y = 0; y < stringLength; y++) {
          char currentCharacter = myArray[x][y];
    
          if (currentCharacter != ' ') {
            count++;
          }
        }
      }
    
      printf("%d\n", count);
    }
    

    编译:

    gcc test.c -o test
    

    然后运行它:

    ./test
    

    它应输出:

    14
    

    根据arrayLength计算,我们现在可以向myArray添加一个单词,并看到输出随期望变化:

    char *myArray[] = {"Oh! ", "Hello ", "world.", "  test     "};
    

    因为只有4个非空格字符(test),所以应输出:

    18
    

答案 3 :(得分:0)

准系统版本,适用于略微低级别的插图:

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

int main() {

char * stringArray[200] = {"O  n e ", " Two  ", "Thre e  ", "Four    ", " F i ve    !"};
int i, j, chars; 
i = j = chars = 0;

while(stringArray[i] != '\0'){
    char temp = stringArray[i][j];
    switch(temp){
        case ' ':
            j++;
            break;
        case '\0':
            i++; 
            j=0;
            break;
        default:
            j++;
            chars++;
            break;           
    }    
}

printf("%d\n", chars);
//o/p == 20

return 0;

}