-1

1,1,1,1,1,1 などのデータ行を含むテキスト ファイルを解析するための次のコードがあります。

while(file >> line)
    {
        words.push_back(line);
    }

    for(int i = 0; i < words.size(); i++)
    {
            if(words.at(i).substr(0, 1) == "[" && words.at(i) != "[header]")
                layers.push_back(words.at(i));

            if(words.at(i).substr(0, 4) == "type")
            {
                temp = words.at(i);
                temp.substr(4, 1);
                types.push_back(temp);
            }

            if(words.at(i) == "[header]")
            {
                map_width = words.at(i+1).substr(6, words.at(i+1).size());
                map_height = words.at(i+2).substr(7, words.at(i+1).size());

                stringstream(map_width) >> width;
                stringstream(map_height) >> height;
            }

            if(words.at(i) == "type=background")
            {
                for(int j = i+1; j <= height + (i+1); j++)
                {
                    int l = 0, m = 1, number = 0, extracted;
                    string extracted_line = words.at(j);

                    for(int k = 0; k <= extracted_line.size(); k++)
                    {
                        cout << number << endl;
                        string ph_character = words.at(j).substr(l, m);
                        if(ph_character == ",")
                        {
                            number = 0;
                            break;
                        }
                        if(ph_character == "0") cout << "Found 0.\n";

                        stringstream(ph_character) >> extracted;
                        number = (number*10) + extracted;

                        switch(number)
                        {
                            case 1:
                                //cout << "Found 1" << endl;
                                break;

                            case 4:
                                cout << "Found 4" << endl;
                                break;
                        }
                        l++; m++;
                    }
                }
            }
    }
    file.close();
}

上記のコードは、ファイルを反復処理し、各行を文字列配列に格納し、各行を文字列に格納してから、文字列の各文字をチェックすることになっています。数値は「,」文字に遭遇するたびにリセットする必要がありますが、出力はクレイジーです:

0
1
11
111
1111
11111
111111
1111111
11111111
111111111
1111111111
-1773790777
-558038505
and so on.

私は何を間違えましたか?出力はファイルの正確な内容である必要があり、通常は 1、1、1、10 の順で、基本的には「,」の前の数字です。code::blocks を使用して Windows XP SP3 を実行しています。

編集:

解析しようとしているファイルのサンプル:

> 1,1,1,1,1,2,23,23,23,23,23,1,1,1,1,1,1,1,1,1
> 10,10,10,23,1,1,1,1,1,1,1,1,23,23,23,23,1,1,1

そのようなデータの行は他にもありますが、この質問をさらにあふれさせる意味はありません。

4

3 に答える 3

1

あなたの問題は、それnumberが保持するのに十分な大きさではない11111111111ので、符号付き整数のオーバーフローが発生し、表示される数値が印刷されることです。あなたはより大きなタイプ、または例えばブーストからのbigintを使用しようとすることができます。

于 2012-10-23T17:39:56.300 に答える
0

インデントを改善し、コードをより明確にしてから、数値の解析を修正する必要があります。明らかに、','区切り文字は数値の前に解析され、その後では解析されません。確かに、あなたのコードは理解するのが難しく (これらすべて.at.substr)、その 80% はword文字列の解析という問題とは関係がありません。

ですから、私があなたの質問を理解していなくても、気にしないでください。


これを改善するための提案を次に示します。

// TODO: add error handling

// TODO: define start and end position of your vector appropriately
std::vector<std::string>::iterator it = words.begin();
std::vector<std::string>::const_iterator end = words.end();

// iterate over your lines
for( ; it != end; ++it) {

    // tokenize using getline
    std::stringstream this_row( *it );
    std::string substr;
    while (std::getline(this_row, substr, ',')) {

        // extract formatted data using stringstream
        std::stringstream str(substr);
        int number;
        str >> number;
        std::cout << number << std::endl;

        // TODO: do whatever you like with that number
    }
}

さらに読むために、お勧めします(そして、私の単純な例よりも優れたエラー処理のために):

于 2012-10-23T18:00:29.033 に答える
0

はい、あなたの番号はあふれています。符号付き 32 ビット int が保持できる最大値は 2147483648 です。11111111111 を出力すると、オーバーフローが発生します。

number = (number*10) + extracted;10回の反復後に数値がオーバーフローしますが、これはまさに起こっていることです。

さらに調査stringstream(ph_character) >> extracted;すると、番号がゼロにリセットされた後、回線が番号を上書きしている可能性があります。条件が数値をゼロに設定している場合、何かが数値を再度上書きしています。通常、これは範囲外の配列にアクセスすることによって発生します。

于 2012-10-23T17:48:00.820 に答える