C程序:在编译时未知长度时设置字符串数组

时间:2012-04-07 17:56:29

标签: c

我正在尝试修改“数组接口示例”部分中显示的示例代码,

http://orclib.sourceforge.net/doc/html/group_g_bind.html

他们使用以下内容将tab_str字符串数组放入OCI_BindArrayOfStrings

char tab_str[1000][21];
...
OCI_BindArrayOfStrings(st, ":s", (char*) tab_str, 20, 0);

问题是,上面的例子在编译时知道数组长度,而我必须在程序运行时从数据库下载这个长度。所以我想创建一个名为my_tab_str的字符串数组,并将其放在以下代码行中:

OCI_BindArrayOfStrings(st, ":s", (char*) my_tab_str, 20, 0);

我的问题是如何设置my_tab_str?这是我的代码(使用gcc -std=C89编译):

int i, arraysize;
char person_name[20] = "";
char * my_tab_str;
...
strncpy(person_name, "John Smith", 19);
arraysize = <this value is downloaded from database>;
...
my_tab_str = malloc( arraysize * sizeof(char) * (strlen(person_name)+1) );
for(i=0;i<arraysize;i++) {
    strncpy( my_tab_str[i], person_name, strlen(person_name) );
}

目标是将“John Smith”(例如10个字节)加上一个空终止字符(我认为由编译器自动添加)放入字符串数组my_tab_str的每个元素中。

我收到了编译警告:warning: passing argument 1 of 'strncpy' makes pointer from integer without a cast /usr/include/string.h:131: note: expected 'char * __restrict__' but argument is of type 'char'

请注意,此处描述了函数OCI_BindArrayOfStrings

http://orclib.sourceforge.net/doc/html/group_g_bind.html#ga502cd4785691b17955f5d99276e48884

并期望一个字符串数组作为参数。有关示例实现,请参阅上面第一个链接的示例代码。

3 个答案:

答案 0 :(得分:2)

对于字符串数组,您需要将my_tab_str声明为char**,然后为其分配内存。

my_tab_str = malloc(ROWS * sizeof(char*)); //ROW is no of strings

然后,

for(int i=0;i<ROWS;i++)
my_tab_str[i] = malloc(COLUMNS * sizeof(char)); //COLUMN is the size for each string.

答案 1 :(得分:1)

从你的帖子中不完全清楚该函数期望作为一个参数。我假设它是char **

在这种情况下,你需要做这样的事情:

// Allocate an array of pointers
char **my_tab_str = calloc(arraysize, sizeof(*my_tab_str));

// Allocate room for each string in turn
for (int i = 0; i < arraysize; i++) {
    // person_name comes from somewhere
    const int len = strlen(person_name);
    my_tab_str[i] = calloc(len+1, sizeof(*my_tab_str[i]));
    strncpy(my_tab_str[i], person_name, len);
}

<强>更新

好的,所以看起来这个函数需要一个char *,它指向连接的所有字符串的连续1D数组,以及字符串的数量和每个字符串的长度。在这种情况下,您需要执行以下操作:

const int len = strlen(person_name);

// Big 1D array
char *my_tab_str = calloc(arraysize*(len+1), sizeof(*my_tab_str));

// Put each string into the 1D array, at regular intervals
for (int i = 0; i < arraysize; i++) {
    strncpy(&my_tab_str[i*(len+1)], person_name, len);
}

这只是猜测,因为该功能确实没有详细记录。

显然,在某些时候你还需要一些清理代码,仔细free一切。

如果你想要非常小心,你应该添加错误处理代码来检查calloc的每个NULL的结果,但这会使示例混乱,所以我省略了它

答案 2 :(得分:1)

看来,字符串表示unsigned char *。你想要一个这样的数组,并且他们正在使用(有点不寻常的)约定,即字符串数组是一个连续的内存块,所以你将其声明为:

unsigned char *my_tab_str;
size_t namesize = 20; // Better still, use a #define so 20 isn't a mysterious magic number

您按如下方式初始化它:

my_tab_str = malloc( arraysize * sizeof( unsigned char *) * (namesize+1) ); // +1 for the null

for( int i = 0; i < arraysize; ++i )
    {
    strncpy( &my_tab_str[i*(namesize+1)], person_name, namesize );
    }

第一行(malloc)为arraysize字符串分配足够的内存,每个字符串都有namesize个字符的空间,加上空值。 strncpy将每个{(1}}个字节复制到最大namesize个字节,然后是空('\ 0')。每次我们将指针传递给下一个位置,即前一个位置namesize+1个字节。