问题描述:

I have the following code for parsing a text file which contains lines of data such as 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();

}

The code above is supposed to iterate over the file, store each line in a string array, store each line in a string then check each character of the string. The number must reset every time it encounters a ',' character, however output is crazy:

0

1

11

111

1111

11111

111111

1111111

11111111

111111111

1111111111

-1773790777

-558038505

and so on.

What have I done wrong? The output should be the exact content of the file which is normally 1, then 1 then 1 then 10, basically the number before the ','. I'm running Windows XP Sp3, using code::blocks.

EDIT:

A sample from the file I'm trying to parse:

> 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

and there's more lines of such data, but there's no point to further flood this question.

网友答案:

Your problem is that number isn't big enough to hold 11111111111 so you get signed integer overflow, creating the numbers you see get printed. You could try to use a larger type, or a bigint from say boost.

网友答案:

Yup, your number is overflowing. The largest value as signed 32-bit int can hold is 2147483648. You see the overflow occurs after you print out 11111111111.

number = (number*10) + extracted; Will cause your number to overflow after 10 iterations, which is exactly what is happening.

Upon further review, the line stringstream(ph_character) >> extracted; could be overwriting your number after it is reset to zero. If the condition is setting the number to zero, something is overwriting number again. Usually, this is caused by accessing an array out of bounds.

网友答案:

You should improve your indentation, make your code clearer and then fix your number parsing. Apparantly your ',' delimiter is parsed before the number, not thereafter. Admittedly, your code is hard to understand (all these .at and .substr) and 80% of it is just not related to the problem, which is the parsing of the word strings, I suppose.

So, if I haven't understood your question, nevermind, you really could have been clearer.


Here's a suggestion how to do better:

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

For further reading I recommend (and for better error handling than in my simple example):

  • Splitting a string in C++
  • How to parse a string to an int in C++?
相关阅读:
Top