0

ファイルから設定を読み取るクイック「構成リーダー」を構築しています。問題は、その関数が「800」文字列を返し、その入力で atol が 0 を返すことです。何が間違っているのかわかりません。

ということで、大まかにこんな感じです。

char *txtval=GetParamFromLine("WINDOW_WIDTH");
val = atol(txtval); 

char* GetParamFromLine(char*parameter)
{
   char text[16];
   //
   // do the reading procedure and fill the text
   //
   return text;
}

結果: atol(text) = 0 (ここで text = "800" )

ご協力いただきありがとうございます!

4

4 に答える 4

3

ローカル スコープの変数へのポインターを返しています。関数呼び出しの後にメモリtextは範囲外になるため、メモリが再利用されるため、メモリへのポインタは意味がありません...

に長期ストレージを割り当てるか、とを同じ関数にtext結合する必要があります。GetParamFromLineatol

于 2013-09-05T20:53:38.903 に答える
2

テキストを静的にする:

char* GetParamFromLine(char*parameter)
{
    static char text[16];
    ... do something
    return text;
}

お使いのバージョンは、おそらく使用される前に上書きされるスタック常駐バージョンを使用しています。静的ストレージ クラス指定子により、

その返されたバッファは、次の GetParameterFromLine の呼び出しまで有効です。

一般に、このような関数への引数として、呼び出し元がバッファーとバッファー サイズを提供する方が適切です。

char *GetParamFromLine(const char *parameter, char *text, size_t text_size)
{
    ... do something
    return text;
}

「何かをする」コードは、そのサイズを注意深く観察する必要があります。実際のデータがバッファーよりも長い場合は、パラメーターを切り捨てるか、空の文字列を返すか、NULL ポインターを返すかなどを決定する必要があります。

于 2013-09-05T20:52:47.167 に答える
2

この問題は、ローカル変数へのポインタを返すことによって発生します。関数GetParamFromLineが戻ると、変数textはスコープ外になります。返されたポインターは無効になり、未定義の動作が発生します。次のように、別の方法でデータを返す必要があります。

std::string txtval=GetParamFromLine("WINDOW_WIDTH");
val = atol(txtval.c_str());

std::string GetParamFromLine(char*parameter)
{
   char text[16];
   //
   // do the reading procedure and fill the text
   //
   return std::string(text);
}

戻り値の型をポインターからローカルに変更するとstd::string、ポインターをローカル変数に返す問題が軽減されます。によって使用されるリソースstd::stringは、オブジェクトによって管理され、自動的にクリーンアップされます。

atol別の方法として、呼び出しを削除して、std::istringstream代わりに a を使用することもできます。利点の 1 つは、これによりエラー報告が改善されることです。

std::string txtval=GetParamFromLine("WINDOW_WIDTH");
std::istringstream iss(txtval);
int val( 0 );
iss >> val;

本当に上を行きたい場合は、文字列の取得と整数データ型への変換の両方を組み合わせて、この新しい関数テンプレートの戻り値の型をパラメーター化できます。

template<typename T>
T GetValueFromLine(const std::string& param) {
    std::string txtval=GetParamFromLine(param.c_str);
    std::istringstream iss(txtval);
    T val = T();
    iss >> val;
    return val;
}

このテンプレートを使用すると、次のことができます。

long wndWidth = GetValueFromLine<long>("WINDOW_WIDTH");
bool showInfo = GetValueFromLine<bool>("SHOW_INFO");
....

注: エラー処理は省略されています。

于 2013-09-05T21:02:53.867 に答える