1

私はこの例を使用しています:

char *myData[][2] =
{{"John", "j@usa.net"},
 {"Erik", "erik@usa.net"},
 {"Peter","peter@algonet.se"},
 {"Rikard","rikard@algonet.se"},
 {"Anders","anders@algonet.se"}};   

char **tableData[6];
tableData[0] = myData[0];
tableData[1] = myData[1];
tableData[2] = myData[2];
tableData[3] = myData[3];
tableData[4] = myData[4];
tableData[5] = NULL;//null terminated array

代わりに、名前とメールに独自の文字列を配置したいと考えています。(文字列 xyz を myData、次に tableData に配置しようとしています) myData を使用した strcpy は機能しません。ポインターと参照のすべての組み合わせを試しましたが、文字列をコピーしていないようです。助言がありますか?

             ok--> strncpy(xyz, argv[i], strlen(argv[i]));
             ok--> strcpy(xyz + strlen(argv[i]), "\0");
run time stops here--> strncpy(myData[i][0], xyz, strlen(xyz));  
                   tableData[i] = myData[i];
4

2 に答える 2

3

初期化されたポインタはmyData[][]、リテラル文字列を指しています。そのメモリに書き込むことはできません。

新しい文字列に新しいメモリを割り当て、新しい文字列へのポインタを に配置できますmyData。または、あなたがしているように見えることについては、ポインタをargv []文字列に保存するだけです(後で文字列を変更する予定がない限り)。

また、文字列をコピーするメモリ ブロックが、新しい文字列を保持するのに十分な大きさであることを確認してください。

Software Monkey 編集: \0 ターミネータを含めます。必要に応じてメモリを解放してください。

于 2008-12-19T00:18:49.243 に答える
0

データの独自のローカル コピーを作成し、リスト内のポインターを変更します。

char **newentry = malloc(sizeof(char*) * 2);
newentry[0] = strdup(myNewName);
newentry[1] = strdup(myNewEmail);
tableData[i] = newentry;

それは簡単な部分です。難しいのは、終了時にメモリを解放することです。これがちょっとした使い捨ての C プログラムである場合は、アプリの終了時にオペレーティング システムがメモリを自動的に解放するため、おそらくメモリを解放しなくても済むでしょう。

しかし、大文字の「P」で適切に実行したい場合は、テーブル項目をコピーして解放するための小さな関数をいくつか作成します。

void tableFreeItem(int i)
{
    if(tableData[i] != 0)
    {
       free(tableData[i][0]);
       free(tableData[i][1]);
       free(tableData[i]);
    }
}

void tableSetItem(int i, char *name, char *email)
{
    tableFreeItem(i);

    tableData[i] = malloc(sizeof(char *) * 2);
    tableData[i][0] = strdup(name);
    tableData[i][1] = strdup(email);
}

これで、リスト内の項目を自由に置き換えることができ、tableFreeItem() 関数を呼び出すことで簡単にメモリを解放できます。これらの関数の使用方法の例を次に示します。

#define TABLE_SIZE 5

char **tableData[TABLE_SIZE + 1]; /* +1 to make room for NULL terminator */

/* Clear out the table. This also sets up the NULL terminator at the end. */
    memset(tableData, 0, sizeof(tableData));

/* Copy the original data into the table */
    for(i = 0; i < TABLE_SIZE; i++)
        tableSetItem(i, mydata[i][0], myData[i][1]);

/* Change a data item */
    tableSetItem(3, "Adam Pierce", "adam@doctort.org");

/* Free memory when we have finished */
    for(i = 0; i < TABLE_SIZE; i++)
        tableFreeItem(i);

免責事項: 私はこのコードをコンパイルまたは実行しようとはしていません。それはおそらくうまくいくでしょう。

于 2008-12-19T00:39:31.883 に答える