-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所以你得到有符号整数溢出,创建你看到打印的数字。您可以尝试使用更大的类型,或者说 boost 中的 bigint。

于 2012-10-23T17:39:56.300 回答
0

你应该改进你的缩进,让你的代码更清晰,然后修复你的数字解析。显然,您的','分隔符是在数字之前解析的,而不是之后。诚然,您的代码很难理解(所有这些.at和),并且其中 80% 与问题无关,我想.substr这是字符串的解析。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 回答