0

strtok から返された文字列をベクターに追加しようとしていますが、何らかの理由で、ファイルにあった最後の文字列しか追加されません...

コード:

// read the remaining lines
// put address and ports into ipaddr and ports, respectively
for (unsigned i = 0; i < numStones; ++i) {
    const char * item;
    fgets(buffer, 255, fp);
    //printf("%s", buffer);
    item = strtok(buffer, " ");
    printf("%s\n", item);
    ipaddr.push_back(item);
    item = strtok(NULL, "\n"); 
    printf("%s\n", item);
    ports.push_back(item);
}
#ifdef _DEBUG
for (unsigned i = 0; i < numStones; i++) {
    printf("IP Address %d: %s\n", i, ipaddr.at(i));
    printf("Port %d: %s\n", i, ports.at(i));
}
#endif

出力:

129.82.47.21
3360
129.82.47.22
5540
129.82.47.23
7732
129.82.47.24
8896
IP Address 0: 129.82.47.24
Port 0: 8896
IP Address 1: 129.82.47.24
Port 1: 8896
IP Address 2: 129.82.47.24
Port 2: 8896
IP Address 3: 129.82.47.24
Port 3: 8896

ご覧のとおり、コードはトークナイザーから正しい文字列を取得していますが、正しい文字列をベクターにプッシュしていません。これは私を夢中にさせています、助けて、ありがとう!

4

3 に答える 3

3

新しいメモリを割り当てずにポインタをプッシュしているためです。バッファ内のある位置へのポインタを常に提供しています。

C ではstrdup、文字列をコピーするために使用します。

C++ では、通常、 を構築し、std::stringそれらを の代わりにベクターに格納しますchar *。ただし、文字列のバッファがどこかに格納されている独自のメモリ管理スキームを使用している場合があります。または、必要に応じて使用できstrdupます。

私は一般的に、別の答えに関するジョナサン・ポッターのコメントに同意します:

ポインターをベクトルに格納することはお勧めできません

プログラミングが初めての場合は、そのアドバイスを 100% 受け入れる必要があります。上級者になると、ポインタをベクトルに入れることが完全に正当な場合があります。


[編集]明確化。

簡単な修正は次のとおりです (はい、通常はそれstrdupが返されなかったことを確認する必要がありますNULL):

ports.push_back(strdup(item));

ただし、ベクトルの処理が終了すると、解放する必要のあるこれらすべてのポインターがあるため、クリーンアップ ジョブが作成されます。

for( int i = 0; i < ports.size(); i++ ) free(ports[i]);

より良い修正はstd::vector<std::string>、メモリを処理するデータ型として使用することです。

于 2013-09-30T02:23:17.837 に答える
0

ベクトルにプッシュしたのはポインタです。したがって、その後for、ベクトルは同じメモリ位置のnumStones時間を格納します。本当の情報を保存する場合はnew、メモリ ブロックに保存してから、ベクトルにプッシュします。

于 2013-09-30T02:22:40.170 に答える
0

これは私にも起こりました。主にこれらのコメントが役に立ちました。char*アドレスが毎回新しいものになるように、新しい文字列を読み取るたびに補助変数を作成して新しくする必要があります。その後、あなたはただpush_back. お気に入り

char* aux = new char[100]; strcpy(aux, your_str); vector.push_back(aux);

于 2018-04-17T11:07:21.377 に答える