0

我正在尝试调整此处“数组接口示例”部分中显示的示例代码,

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 个字节)加上一个空终止字符(我认为它是由编译器自动添加的)到 strings 数组的每个元素中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 _ _

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

4

3 回答 3

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.
于 2012-04-07T18:03:09.023 回答
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);
}

更新

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

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处理所有内容。

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

于 2012-04-07T18:02:42.143 回答
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复制到它们每个中的最大 字节数namesize,后跟一个空值 ('\0')。每次我们传递一个指向下一个位置的指针,即namesize+1超出前一个位置的字节。

于 2012-04-07T18:11:00.880 回答