使用 ifstream getline 意外退出循环
unexpected exit of loop with ifstream getline
请看下面的代码:
std::string s;
while(std::getline(m_File,s))
{
std::cout<<"running\n";
std::string upper(s);
std::transform(upper.begin(),upper.end(),upper.begin(),toupper);
if(upper.find("*NODE") != std::string::npos)
{
std::cout<<"start reading nodes\n";
readnodes();
}
std::cout<<"\n open? "<<m_File.is_open()<<"\n";
}
我正在尝试从以下输入文件中提取数据。(INPUT FILE)
*NODE
1 ,1.0,2.0
2, 2.6,3.4
3, 3.4, 5.6
*NODE
4, 4, 5
5, 5, 6
但是当我 运行 这个时,程序找到 *NODE 的第一个实例并调用 readnode() 函数,但是 无法识别第二个实例*节点。
m_File 是同一 class 的 ifstream 对象,其中 readnode() 被定义为私有函数。
读取节点() :
void mesh::readnodes()
{
char c;
int id;
float x,y;
while(m_File>>id>>c>>x>>c>>y)
{
node temp(id,x,y);
m_nodes.push_back(temp);
// dummy string for reading rest of line.
std::string dummy;
std::getline(m_File,dummy);
}
}
为什么意外退出?
while(m_File>>id>>c>>x>>c>>y)
{
node temp(id,x,y);
m_nodes.push_back(temp);
// dummy string for reading rest of line.
std::string dummy;
std::getline(m_File,dummy);
}
在上面的代码中,m_File>>id>>c>>x>>c>>y
用于读取id,x,y
,但在读取前几行节点后,它在m_File>>id>>c>>x>>c>>y
失败时中断,这也可能改变m_File
状态。结果,getline(m_File, s)
return false,导致意外退出。
解决方案:
我没有找到基于您的原始程序的解决方案。但是既然你想从字符串中提取值,那么 boost 可能是一个更好的解决方案,检查:
while (getline(m_File, s))
{
if (boost::to_upper_copy(s) == "*NODE") continue;
std::vector<std::string> SubStr;
boost::algorithm::split(SubStr, s, boost::is_any_of(" ,"));
SubStr.erase(std::remove(SubStr.begin(), SubStr.end(), ""), SubStr.end());
m_nodes.push_back(node(atoi(SubStr[0].c_str()), atof(SubStr[1].c_str()), atof(SubStr[2].c_str())));
}
获取结果:
for (auto Itr : m_nodes)
std::cout << Itr.id << "," << Itr.x << "," << Itr.y << std::endl;
Output
1,1.0,2.0
2,2.6,3.4
3,3.4,5.6
4,4,5
5,5,6
感谢您找出 readnode() 函数中 while 循环条件中的错误。
更好的解决方案是如下更改 readnode() 函数。
void mesh::readnodes()
{
char c; //temp.variable for recieving ','.
int id;
float x,y;
std::string temp;
// changes made in the while loop condition
while(m_File.peek() != '*' and m_File.peek() != EOF )
{
//getline(m_File,temp);
m_File>>id>>c>>x>>c>>y;
node temp(id,x,y);
m_nodes.push_back(temp);
// dummy string for reading rest of line.
std::string dummy;
std::getline(m_File,dummy);
}
}
请看下面的代码:
std::string s;
while(std::getline(m_File,s))
{
std::cout<<"running\n";
std::string upper(s);
std::transform(upper.begin(),upper.end(),upper.begin(),toupper);
if(upper.find("*NODE") != std::string::npos)
{
std::cout<<"start reading nodes\n";
readnodes();
}
std::cout<<"\n open? "<<m_File.is_open()<<"\n";
}
我正在尝试从以下输入文件中提取数据。(INPUT FILE)
*NODE
1 ,1.0,2.0
2, 2.6,3.4
3, 3.4, 5.6
*NODE
4, 4, 5
5, 5, 6
但是当我 运行 这个时,程序找到 *NODE 的第一个实例并调用 readnode() 函数,但是 无法识别第二个实例*节点。 m_File 是同一 class 的 ifstream 对象,其中 readnode() 被定义为私有函数。
读取节点() :
void mesh::readnodes()
{
char c;
int id;
float x,y;
while(m_File>>id>>c>>x>>c>>y)
{
node temp(id,x,y);
m_nodes.push_back(temp);
// dummy string for reading rest of line.
std::string dummy;
std::getline(m_File,dummy);
}
}
为什么意外退出?
while(m_File>>id>>c>>x>>c>>y)
{
node temp(id,x,y);
m_nodes.push_back(temp);
// dummy string for reading rest of line.
std::string dummy;
std::getline(m_File,dummy);
}
在上面的代码中,m_File>>id>>c>>x>>c>>y
用于读取id,x,y
,但在读取前几行节点后,它在m_File>>id>>c>>x>>c>>y
失败时中断,这也可能改变m_File
状态。结果,getline(m_File, s)
return false,导致意外退出。
解决方案:
我没有找到基于您的原始程序的解决方案。但是既然你想从字符串中提取值,那么 boost 可能是一个更好的解决方案,检查:
while (getline(m_File, s))
{
if (boost::to_upper_copy(s) == "*NODE") continue;
std::vector<std::string> SubStr;
boost::algorithm::split(SubStr, s, boost::is_any_of(" ,"));
SubStr.erase(std::remove(SubStr.begin(), SubStr.end(), ""), SubStr.end());
m_nodes.push_back(node(atoi(SubStr[0].c_str()), atof(SubStr[1].c_str()), atof(SubStr[2].c_str())));
}
获取结果:
for (auto Itr : m_nodes)
std::cout << Itr.id << "," << Itr.x << "," << Itr.y << std::endl;
Output
1,1.0,2.0
2,2.6,3.4
3,3.4,5.6
4,4,5
5,5,6
感谢您找出 readnode() 函数中 while 循环条件中的错误。 更好的解决方案是如下更改 readnode() 函数。
void mesh::readnodes()
{
char c; //temp.variable for recieving ','.
int id;
float x,y;
std::string temp;
// changes made in the while loop condition
while(m_File.peek() != '*' and m_File.peek() != EOF )
{
//getline(m_File,temp);
m_File>>id>>c>>x>>c>>y;
node temp(id,x,y);
m_nodes.push_back(temp);
// dummy string for reading rest of line.
std::string dummy;
std::getline(m_File,dummy);
}
}