[英]How do I print out an array of string(array) create by char ** in C?
I'm new to C and trying to create an array using char **, but I'm having a problem printing it out.我是 C 的新手,并试图使用 char ** 创建一个数组,但我在打印它时遇到了问题。 Is there a way to print it out or shouldn't I use this way to create an array of string?有没有办法打印出来,或者我不应该用这种方式来创建一个字符串数组?
int main()
{
char **a = {"abc", "ddd", "ccc", "aaa"};
for (size_t i = 0; i < 4; i++){
printf("%s\n", a+i); // only print out "abc" correctly
// printf("%s\n", *(a+i)); doesn't work
// printf("%s\n", a[i]); doesn't work
}
return 0;
}
This declaration本声明
char **a = {"abc", "ddd", "ccc", "aaa"};
is incorrect.是不正确的。 A scalar type may be initialized using only a single expression in braces.标量类型可以仅使用大括号中的单个表达式进行初始化。
If you want to declare an array of pointers then you should write如果你想声明一个指针数组,那么你应该写
char * a[] = {"abc", "ddd", "ccc", "aaa"};
To output it you can write要输出它,你可以写
for (size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++){
puts( a[i] );
}
Or或者
char * a[] = {"abc", "ddd", "ccc", "aaa"};
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++){
puts( a[i] );
}
Another approach is to declare a two-dimensional array like for example另一种方法是声明一个二维数组,例如
char a[][4] = {"abc", "ddd", "ccc", "aaa"};
It can be outputted the same way as shown above.可以像上图一样输出。
for (size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++){
puts( a[i] );
}
If you want to have a declaration of an object of the type char **
like如果你想声明一个char **
类型的对象,比如
char **a = /*...*/;
then you could initialize it with a compound literal.然后你可以用复合文字初始化它。
Here is a demonstrative program.这是一个演示程序。
#include <stdio.h>
int main(void)
{
enum { N = 4 };
char **a = ( char * [N] ){"abc", "ddd", "ccc", "aaa"};
for ( size_t i = 0; i < N; i++ )
{
puts( a[i] );
}
return 0;
}
Its output is它的输出是
abc
ddd
ccc
aaa
running the posted code through the compiler results in:通过编译器运行发布的代码会导致:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
8 | char **a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
8 | char **a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
8 | char **a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
8 | char **a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
11 | printf("%s\n", a+i); // only print out "abc" correctly
| ~^ ~~~
| | |
| char * char **
Compilation finished successfully.
when compiling, do NOT ignore the warnings.编译时,不要忽略警告。
That final line from the compiler:编译器的最后一行:
Compilation finished successfully
only means the compiler used some 'workaround' for each of the problems, NOT that the correct code was produced.仅意味着编译器对每个问题都使用了一些“解决方法”,而不是生成了正确的代码。
If we make a change so only a single pointer is used rather than a pointer to pointer:如果我们进行更改,因此仅使用单个指针而不是指向指针的指针:
#include <stdio.h>
int main( void )
{
char *a = {"abc", "ddd", "ccc", "aaa"};
for (size_t i = 0; i < 4; i++){
printf("%s\n", a+i); // only print out "abc" correctly
// printf("%s\n", *(a+i)); doesn't work
// printf("%s\n", a[i]); doesn't work
}
return 0;
}
results in:结果是:
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
8 | char *a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
8 | char *a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
8 | char *a = {"abc", "ddd", "ccc", "aaa"};
| ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
which is better, but still not right.哪个更好,但仍然不对。
modifying the declaration of a[]
so it is appropriately declared and initialized results in:修改a[]
的声明,以便对其进行适当的声明和初始化,结果如下:
char *a[]
which reads as an array of pointers to char它读取为指向 char 的指针数组
the next problem is:下一个问题是:
printf("%s\n", a+i);
which results in:这导致:
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
that is corrected by:通过以下方式更正:
printf("%s\n", *(a+i) );
so a passable, but not great version of the code looks like:所以一个可以通过但不是很好的代码版本看起来像:
#include <stdio.h>
int main( void )
{
char *a[] =
{
"abc",
"ddd",
"ccc",
"aaa"
};
for (size_t i = 0; i < 4; i++){
printf("%s\n", *(a+i) ); // only print out "abc" correctly
// printf("%s\n", *(a+i)); doesn't work
// printf("%s\n", a[i]); doesn't work
}
return 0;
}
However, that has the 'magic' number 4
.然而,这有“魔法”数字4
。
We can eliminate that 'magic' number by letting the compiler perform the calculations for the for()
loop:我们可以通过让编译器为for()
循环执行计算来消除这个“神奇”数字:
for( size_t i = 0; i < (sizeof(a) / sizeof( *a ); i++ )
So the final code is: (with excess blank lines removed)所以最终的代码是:(去掉多余的空行)
#include <stdio.h>
int main( void )
{
char *a[] =
{
"abc",
"ddd",
"ccc",
"aaa"
};
for (size_t i = 0; i < (sizeof( a ) / sizeof( *a )); i++)
{
printf("%s\n", *(a+i) );
}
return 0;
}
The result of running the above code is:运行上面代码的结果是:
abc
ddd
ccc
aaa
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.