C ++文件输入中的意外输出

时间:2012-10-23 17:36:10

标签: c++ parsing file-io

我有以下代码用于解析包含数据行的文本文件,例如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,基本上是','之前的数字。我正在运行Windows XP Sp3,使用code :: blocks。

编辑:

我正在尝试解析的文件中的示例:

> 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

并且还有更多这样的数据,但没有必要进一步解决这个问题。

3 个答案:

答案 0 :(得分:1)

您的问题是number不足以容纳11111111111,因此您会收到有符号整数溢出,从而创建您看到的数字。您可以尝试使用更大的类型,或者说来自boost的bigint。

答案 1 :(得分:0)

是的,你的号码满溢。有符号32位int可以容纳的最大值是2147483648.您会看到在打印出11111111111后发生溢出。

number = (number*10) + extracted;将导致您的号码在10次迭代后溢出,这正是发生的事情。

进一步审核后,stringstream(ph_character) >> extracted;行可能会在重置为零后覆盖您的号码。如果条件是将数字设置为零,则会再次覆盖数字。通常,这是由于访问数组越界而引起的。

答案 2 :(得分:0)

您应该改进缩进,使代码更清晰,然后修复数字解析。 显然,您的','分隔符在数字之前被解析,而不是之后。不可否认,您的代码很难理解(所有这些.at.substr),其中80%与问题无关,即word字符串的解析,I假设

所以,如果我没有理解你的问题,请不要理解,你真的可以更清楚。


以下是如何做得更好的建议:

// 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
    }
}

为了进一步阅读,我建议(并且为了比我的简单示例更好的错误处理):