C 文件输入中的意外输出
Unexpected output in C++ file input
我有以下代码,用于解析包含数据行的文本文件,例如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,然后是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
还有更多这样的数据行,但是没有意义可以进一步泛滥这个问题。
您的问题是number
不足以容纳11111111111
,因此您会签名整数溢出,从而创建您看到的数字被打印出来。您可以尝试使用较大的类型,也可以使用Bigint。
是的,您的电话号码溢出。签名的32位INT可以保持的最大价值是2147483648。您会看到打印出1111111111的溢出。
number = (number*10) + extracted;
将使您的电话号码在10次迭代后溢出,这正是正在发生的事情。
在进一步审核后,stringstream(ph_character) >> extracted;
可以在将其重置为零后覆盖您的电话号码。如果条件将数字设置为零,则有些东西再次覆盖数字。通常,这是由于访问界限的阵列而引起的。
您应该改善缩进,使代码更清晰,然后修复编号解析。显然,您的','
定界符是在数字之前解析的,此后不是。诚然,您的代码很难理解(所有这些.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
}
}
为了进一步阅读,我推荐(并且要比我的简单示例中的错误处理更好):
- 在C ? 中拆分字符串
- 如何将字符串解析为c 中的int?
- 字符串比较中的意外输出
- 来自 decltype 的意外输出类型
- 字符数组到十六进制字符串的转换 - 意外输出
- 使用 boost::regex 从目录中获取带有一些正则表达式的文件名称时出现意外输出
- 使用后序遍历递归的深度优先搜索会产生意外输出
- C++的意外输出
- 贝金纳C++练习解决方案的意外输出
- 无效* 转换获得意外输出
- 以下程序的意外输出
- 意外输出:矢量矢量(功率集)
- 基本 int 数组提供意外输出
- 线程的意外输出
- 减法中的意外输出
- 带有左移操作员C 的意外输出
- C strncpy意外输出
- 意外输出..函数绑定在虚拟表中的发生方式
- 星号的意外输出
- 已编译的 protobuf 文件的意外输出路径
- 打印对象矢量的意外输出
- 递归函数用于计算 n 个数字之和的意外输出