我有以下代码用于解析包含数据行的文本文件,例如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
并且还有更多这样的数据,但没有必要进一步解决这个问题。
答案 0 :(得分:1)
您的问题是number
不足以容纳11111111111
,因此您会收到有符号整数溢出,从而创建您看到的数字。您可以尝试使用更大的类型,或者说来自boost的bigint。
答案 1 :(得分:0)
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
}
}
为了进一步阅读,我建议(并且为了比我的简单示例更好的错误处理):