1

解析関数に問題があったため、実行時に特定の変数の値を伝えるためにいくつかの cout ステートメントを配置しました。atoi が文字を正しく変換していないと思います。

奇妙な動作をしている私のコードの短いスニペットを次に示します。

c = data_file.get();
if (data_index == 50)
    cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl;

このステートメントの出力は次のとおりです。 50 digit 0 = '5' number = 52

私はループ内でこのコードを呼び出していますが、最初の 47 文字を正しく変換し、48 文字目には整数の後に 0 を追加し、49 文字目には 1 を追加し、50 文字目には 1 を追加します (見たここでは 2 が追加され、57 番目の文字まで 9 が追加されます。その後、239 番目の文字まで正しく変換されます。

これは奇妙ですか、それとも何ですか?

もう少し明確にするために、関数全体を投稿します。この関数には、空の double 配列 (ping_data) へのポインターが渡されます。

int parse_ping_data(double* ping_data)
{
    ifstream data_file(DATA_FILE);

    int pulled_digits [4];
    int add_data;
    int loop_count;
    int data_index = 0;

    for (char c = data_file.get(); !data_file.eof(); c = data_file.get())
    {
        if (c == 't' && data_file.get() == 'i' && data_file.get() == 'm' && data_file.get() == 'e' && data_file.get() == '=')
        {
            loop_count = 0;
            c = data_file.get();
            if (data_index == 50)
                    cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl;
            pulled_digits[loop_count] = atoi(&c);

            while ((c = data_file.get()) != 'm')
            {
                loop_count++;
                if (data_index == 50)
                    cout << "50 digit " << loop_count << " = '" << c << "' number = " << atoi(&c) << endl;
                pulled_digits[loop_count] = atoi(&c);
            }
            add_data = 0;
            for (int i = 0; i <= loop_count; i++)
                add_data += pulled_digits[loop_count - i] * (int)pow(10.0,i);

            if (data_index == 50)
                cout << "50 index = " << add_data << endl;
            ping_data[data_index] = add_data;
            data_index++;

            if (data_index >= MAX_PING_DATA)
            {
                cout << "Error parsing data. Exceeded maximum allocated memory for ping data." << endl;
                return MAX_PING_DATA;
            }   
        }
    }

    data_file.close();

    return data_index;
}
4

3 に答える 3

7

atoichar単一へのポインタではなく、文字列、つまり s の null で終了する配列を取るcharため、これは正しくなく、予測できない結果が得られます。

char c;
//...
/* ... */ atoi(&c) /* ... */

また、atoiエラーを検出する方法も提供していないため、preferstrtolおよび同様の機能を使用します。

例えば

char *endptr;
char c[2] = {0}; // initalize c to all zero

c[0] = data.file.get(); // c[1] is the null terminator

long l = strtol(c, &endptr, 10);

if (endptr == c)
    // an error occured
于 2009-11-27T20:16:50.060 に答える
3

atoi入力として null で終わる文字列が必要です。あなたが提供しているのは、ヌルで終わる文字列ではありません。

atoiそうは言っても、適切に使用するのは非常に難しい(可能な場合でも)ことは常に付け加えておく価値があります。atoiエラー制御もオーバーフロー制御も提供しない関数です。C 標準ライブラリで文字列表現から数値への変換を実行する唯一の適切な方法は、strto...グループの関数です。

実際には、1 文字の数字だけを変換する必要がある場合、atoiまたはその他の文字列変換関数を使用するのは奇妙なやり過ぎです。すでに提案されているように、必要なのは0、文字の数字の値から の値を引いて、対応する数値を取得することだけです。言語仕様は、これが移植可能なソリューションであることを保証します。

于 2009-11-27T20:30:55.970 に答える
2

気にしないでください。文字を \0 で終わる文字列に変換する必要があっただけです。私はそれをこのコードに変更しました:

文字バッファ [2];

バッファ[1] = '\0';

buffer[0] = data_file.get();

場合 (data_index == 50)

cout << "50 digit 0 = '" << buffer[0] << "' number = " << atoi(buffer) << endl;

そしてそれはうまくいきました。

于 2009-11-27T20:21:10.203 に答える