所以我有这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char field1[45];
char field2[444];
char *fields[] = {
field1, field2
};
int main (int argc, char *argv[])
{
sprintf(fields[0], "hello\n");
printf(fields[0]);
}
我不需要使用field1和field2访问字段。有没有一些速记方式来做到这一点?我尝试了以下不起作用。
char *fields[] = { char[45], char[444] };
基本上我想我想要一个包含不同长度字符串的数组,而不必使用malloc。
答案 0 :(得分:1)
我想你可能想要一个结构。
struct fields {
char field1[45];
char field2[444];
};
struct fields theFields[100];
我没有看到多维数组。
答案 1 :(得分:1)
基本上我想我想要一个包含不同长度字符串的数组,而不必使用malloc。
更确切地说,你想要一个&#34;锯齿状的&#34;数组,其中每个fields[i]
的物理大小可以不同(即fields[0]
为8个字符的字符串保留足够的空间,fields[1]
保留足够的空间对于20个字符的字符串等),您仍然需要常规的多维数组语法才能工作。
不幸的是,您无法使用常规数组声明语法。
如果你真的不想搞乱动态内存,可以尝试的一件事是设置一个大的1D数组作为后备存储,然后将指针存储到该数组中。这就是我刚刚蠢蠢的事情:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define HUGE 128
static char backing_store[HUGE];
static size_t backing_store_used = 0;
char *add_string( const char *str )
{
char *p = NULL;
if ( strlen( str ) < HUGE - backing_store_used )
{
p = &backing_store[backing_store_used];
strcpy( p, str );
backing_store_used += strlen( str ) + 1;
}
return p;
}
int main( void )
{
char *strs[5] = {NULL};
strs[0] = add_string("foo");
strs[1] = add_string("blurga");
strs[2] = add_string("supercalifragilisticexpealidocious");
for ( size_t i = 0; i < 3; i++ )
{
printf( "strs[%zu] = %s (%zu), strs[%zu][1] = %c\n", i, strs[i], strlen( strs[i] ), i, strs[i][1] );
}
int printed = 0;
for ( size_t i = 0; i < HUGE; i++ )
{
if ( printed > 80 )
{
putchar( '\n' );
printed = 0;
}
printed += printf( isprint( backing_store[i] ) ? "%c " : "'\\0%o' ", backing_store[i] );
}
putchar( '\n' );
return 0;
}
这是输出:
[fbgo448@n9dvap997]~/prototypes/stringspace: ./stringspace
strs[0] = foo (3), strs[0][1] = o
strs[1] = blurga (6), strs[1][1] = l
strs[2] = supercalifragilisticexpealidocious (34), strs[2][1] = u
f o o '\00' b l u r g a '\00' s u p e r c a l i f r a g i l i s t i c e x p e a l
i d o c i o u s '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00'
'\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00'
'\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00'
'\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00'
'\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00'
'\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00' '\00'
'\00' '\00'
因此,您可以假装您的strs
数组是一个不同物理长度的字符串数组。
显然,您需要进行一些分析,看看您需要多大才能为要保存的字符串的数量和长度进行后备存储。
这非常适合设置您不打算更改的字符串的静态列表。如果你想编辑不同长度的字符串,或删除字符串或类似的东西,这会让人感到不快,你基本上写了一个你自己的动态内存管理器的破碎版本,此时你可能会好好使用malloc
和朋友。
答案 2 :(得分:1)
您所呈现的是不多维数组声明。它是指向char
的指针数组的声明,您恰好将其初始化为两个指针的数组,一个指向两个char
数组中每个指针的第一个元素。 必须了解数组和指针不是同一个东西。在这种特殊情况下,一个结果是两个1D数组不保证在内存中相邻,也不在内存中以相同的顺序排列,因为它们的指针在数组中。
由于多维数组是其元素为数组的数组,因此作为推论,指针数组不是多维数组。数组类型值衰减到指针的事实可能会混淆情况,但它不会改变它。
现在回答你的实际问题,没有没有简便的方法来初始化一个指针数组,比如你提供的值与你提供的值相当。有效的指针指向某个东西,你必须在某个地方声明某些东西(否则)。,如注释中提到的@immibis和@ M.M先前的回答,你可以使用数组文字而不是命名数组。有关语法,请参阅@ M.M的答案。但是,我重申,这是一个指针数组,而不是2D数组。
正如其他答案已经观察到的那样,还有其他数据结构可以提供更多关于布局和排序的保证,也许其中一种可以更好地满足您的实际需求,但其中没有一种比您提供的更短。
基本上我想我想要一个包含不同长度字符串的数组,而不必使用malloc。
尽管有上述任何一项,但如果您提交的工作代码实际上符合您的目的,那么它就没有任何问题。但是,根据不同长度的字符串数组的含义,这可能是另一种选择:
char fields[2][444];
两个数组元素 - 每个数组包含444 char
个 - 每个数组元素都可以容纳任意长度的字符串,最长可达443 chars
,字符串取决于字符串终止符数组中的位置。你不打算使用第一个元素的399个字节并不一定是个大问题。
做这样的事情也可能很方便:
char fields[][444] = { "a short string", "a somewhat longer string, ya know" };
请注意,在这种情况下,引用的字符序列是成员数组的 initializers 。在这种情况下不涉及指针。
答案 3 :(得分:1)
你可以写:
char *fields[] = {
(char[45]) { 0 },
(char[444]) { 0 }
};
我建议不要使用这种设计,因为它很难执行检查,以至于你不会超越缓冲区。