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) );
}

目標は、string の配列の各要素に "John Smith" (たとえば 10 バイト) と null 終了文字 (コンパイラによって自動的に追加されると思います) を配置すること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);
}

アップデート

char *わかりました、その関数は、文字列の数と各文字列の長さとともに、連結されたすべての文字列の連続した 1D 配列を指す which を取るように見えます。その場合、次のようなことを行う必要があります。

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文字と null を格納します。それらのstrncpyそれぞれに最大 namesizeバイト数をコピーし、その後にヌル ('\0') を続けます。次の場所へのポインターを渡すたびにnamesize+1、前の場所を超えるバイトです。

于 2012-04-07T18:11:00.880 に答える