我正在尝试计算总字符数,不包括空格,(我相信)是一个指向字符串数组的指针,名为myArray。
我正在努力找出问题所在。任何帮助将不胜感激!
char *myArray[1000] = {"Oh! ", "Hello ", "world."};
int count = 0, x;
for (x = 1; x <= 1000; ++x) {
count += strlen(myArray[x]);
}
printf(count);
期望的输出:
14
答案 0 :(得分:6)
Yuu可以使用ctype.h
中的标准函数来识别字符类。例如,使用issspace()
可以查找字符是否为空格,如果是,则可以忽略它。
您正在将索引从1循环到1000. C中的索引从0开始并上升到N-1。此外,你只包含3个指针; rest只是NULL(隐式零初始化)。
另一个问题是您在没有格式说明符的情况下打印count
。 count
为int
,您需要使用%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的回答。我会解决一些问题,包括原始问题中关于不计算空格的要点:
重申一下,C数组是0索引的。
您可能想要一个无界循环,这样您就可以在不更改代码的情况下向数组中添加更多元素(并且数字1000
会使解决方案回旋)。此时,x
的最大值变为sizeof(myArray) / sizeof(myArray[0])
,即元素数量。您还可以让编译器通过从1000
的定义中删除myArray
来决定制作数组的大小:char *myArray[] = {"Oh! ", "Hello ", "world."};
顶级循环计算完整字符串的字符串长度,但您只需要非空格字符。有很多方法可以做到这一点,但最直接的方法是在嵌套循环中计算非空格字符。
鉴于这些,下面的代码获得了所需的输出:
#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;
}