char *

2012-04-27 3 views
2

の配列からデータ構造体を返そうとしています。データ構造体の中で、1つのメンバがchar*型の配列で、もう1つがint型の関数urlTokenerからデータ構造体を返そうとしています。関数urltokenerで配列の値を出力すると、正しい型が得られますが、返されたデータ構造体が使用されているmain関数では、出力が正しくないため配列に正しい値が含まれていません関数と同じではありません)。関数がデータ構造体を正しく返さないようです。私が次のコードで間違っていることを確認して言うことができますか?char *

#include <string.h> 
#include <stdio.h> 

struct tokenDetail 
{ 
    char* theArray[256]; 

    int sizeOfArray; 
}; 


tokenDetail urlTokener(const char *,char*); 

void main() 
{ 
    // String to be splitted. 
    const char* url="/v1/AUTH_abb52a71-fc76-489b-b56b-732b66bf50b1/images?limit=1000&delimiter=/&format=xml" ; 

    tokenDetail newdetails; 
    newdetails=urlTokener(url,"?"); 
    for (int i=0;i<newdetails.sizeOfArray;i++) 
    { 
     printf("This is in main where size is %d and the value %s\n",newdetails.sizeOfArray,newdetails.theArray[i]); 
    } 
} 

tokenDetail urlTokener(const char* urlLine,char* delimiter) 
{ 
    char urlArray[256]; 
    strncpy(urlArray, urlLine, sizeof(urlArray)); 
    tokenDetail details; 
    unsigned int index = 0; 
    details.theArray[index] = strtok(urlArray, delimiter); 

    while(details.theArray[index] != 0) 
    { 
     printf("This is in function %s\n",details.theArray[index]); 
     ++index; 
     details.theArray[index] = strtok(0, delimiter); 
    } 
    for (int i=0;i<index;i++) 
    { 
     printf("This is in function 2nd time %s\n",details.theArray[i]); 
    } 
    details.sizeOfArray=index; 
    return details; 
} 

ご注意:私は、C++のためにそれをやっているが、私は名前空間std、およびライブラリの文字列を使用する(私は、このタスクを与えた人物によって)許可されていませんよ。これはコードがCに似ている理由です。この制限のため、私はCまたはC++にタグを付けるかどうか混乱します。だから私はcとC++の両方でタグ付けしました。あなた自身を決めることができるかもしれない。

+0

はそれがurlArray'は 'ということだろうスタック変数? 'details.theArray'のポインタは、' urlArray'のアドレスを指しています。これは、関数から戻ると有効ではありません。 –

+0

私は非常に徹底的には読んでいませんが、 'printf'、' strtok'などの大量の使用はcであることを意味しています。したがって、コピー管理者と代入演算子に関するLuchian Grigoreの答えは関係ありません。 cやC++が必要かどうかを明確にし、必要に応じてタグを変更してください。 – BoBTFish

+0

私はC++で行う必要があるが、名前空間Stdと文字列ライブラリを使用できない大きなプロジェクトに対してこのテストを行っています。私はcstringまたはstring.hとstdio.hしか使用できません。だから、確かにC++ですが、私はcと似たようなものをたくさん使う必要があります。あなたの混乱を取り除くことを願っています。 @ Bobtfish –

答えて

3

は 今度はあなたが関数から返された後に存在する を停止し、あなたのurlArray、ローカル変数、にポインタであるstrtok、から返されました。

これはCかC++ですか?両方のラベルを設定してあり、解決方法は です。 C++では、明らかな解決策は、 tokenDetailchar*std::stringに置き換えることです。 Cでは、もう少し複雑です。 非標準だが広く普及しているstrdupを使用して構造体に文字列を動的に割り当て、クライアントに を解放する必要があります。ここでの通常の解決方法は、TokenDetailが動的に割り当てられた へのポインタと、返されたポインタでクライアントが呼び出す必要がある の関数に戻ります。この は、あなたの割り当てや解放をどのように自由に行えますか? ( 通常のソリューションであり、実際には、クライアントのみに TokenDetailの前方宣言を提供するために、彼らはその要素にアクセスするために呼び出す を持っている機能を提供する。)

0

コピーコンストラクタ、デストラクタ、または代入演算子を実装していません。

コピーコンストラクタはreturn details;で呼び出されますが、デフォルトのコピーコンバーターはシャローコピーしか行われないため、フィールドchar* theArray[256];は正しくコピーされません。

+0

C++の場合、唯一の正しい答えは 'std :: string'を使うことです(この場合、デフォルトのコピーコンストラクタなどは問題ありません)。コードがC言語の場合、コピーコンストラクタなどは使用できません。 –

+0

@JamesKanzeそれはC++だ、opはコメントでそれを言い、私は質問を編集した。あなたは正しいです、std :: stringを使用して行く方法です。 +1 –

2

ここでの問題は、tokenDetailには手書きコピーコンストラクタ、デストラクタまたは代入演算子が必要でないことです。問題は、ローカル変数urlArrayurlTokener()のままになると破棄されるため、details.theArrayの要素が指す位置が無効になることです。もちろん、返されたtokenDetailも同様です。あなたは、ポインタの配列を充填している