当你不知道你将在字符串中放入多少元素时,有没有办法初始化结构中的字符串数组?

时间:2017-01-02 01:34:36

标签: c arrays struct

我有这个结构:

typedef struct SomeStruct {
  char someString[];
} SomeStruct;

这会产生错误,因为初始化时未定义someString的大小。

我想让someString成为一个字符串数组,但我不知道初始化时数组的大小。 (将在数组中的元素将取决于程序中稍后的用户输入。)

是否可以在不知道数组大小的情况下将其初始化为字符串数组?

3 个答案:

答案 0 :(得分:2)

是的,C标准在7.2.18-26中讨论了这个问题。您所描述的内容称为结构的灵活数组成员。从标准:

  

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这被称为灵活的阵列成员。

基本上它是说,如果结构的最后一个成员是一个未定义大小的数组(可能是运行时大小的情况),那么在使用结构时,你将分配你的结构的适当大小,包括你想要字符串的大小。例如:

typedef struct SomeStruct {
    char someString[];
} SomeStruct;

具有灵活的数组成员someString。使用它的常用方法是:

SomeStruct *p = malloc(sizeof (SomeStruct) + str_size);

假设对malloc的调用成功,p指向的对象在大多数情况下表现得好像p已被声明为:

struct {char someString[str_size]; } *p;

阅读标准了解更多详情。时髦词flexible array member也会显示很多信息。 wikipedia是一个很好的起点。

答案 1 :(得分:1)

您可以使用具有灵活数组的结构。例如

typedef struct SomeStruct 
{
    size_t n; 
    char someString[];
} SomeStruct;

其中n用于存储数组中元素的数量。

然后您可以按照以下方式创建结构对象

SomeStruct *s = malloc( sizeof( SomeStruct ) + 10 * sizeof( char[100] ) );
s->n = 10;

答案 2 :(得分:1)

如果你不能使用动态数组(听起来像这样,如果你得到编译错误),你实际上可以超越数组,只要它在结束时struct,只要你能真正访问那个内存。例如:

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

typedef struct SomeStruct {
  char someString[10];
} SomeStruct;

int main (void)
{
    // Allocate 4x space, so we have room to overrun
    SomeStruct *p = malloc(sizeof(SomeStruct) * 4);

    p->someString[38] = 'a';
    printf("%c\n", p->someString[38]);
}

当然,您仍然需要实际分配空间,因此根据您的情况,它可能对您没那么有用。