C++ 字符串流问题:getline 不适用于 stringstream
C ++ string stream issue: getline doesn't work with stringstream
我编写了一个程序,它获取一个文件并将其读入 class 中的字符串流字段,现在我正尝试与它进行交互。问题是,当从几种方法中顺序读取时,其中一种方法会出错,或者根本不起作用。我想问题是我如何读取文件,我应该如何改进它?
有我的class:
class MatReader
{
protected:
...
stringstream text;
...
string PhysicsMaterial;
string Diffuse;
string NMap;
string Specular;
public:
/// <summary>
/// Read all lines in .mat document by string
/// </summary>
void ReadAllLines(string file_path);
/// <summary>
/// Getting PhysicsMaterial property
/// </summary>
string getPhysMaterial();
/// <summary>
/// Getting diffuse file path
/// </summary>
string getDiffuseLocation();
};
还有我的实现文件:
#include "MaterialHandler.h"
void MatReader::ReadAllLines(string mat_file)
{
ifstream infile(mat_file);
string str;
if (infile.is_open())
{
ofile = true;
while (!infile.eof())
{
getline(infile, str);
text << str+"\n";
}
}
else
throw exception("[ERROR] file does not exist or corrupted");
}
string MatReader::getPhysMaterial()
{
string line;
vector<string> seglist;
try
{
if (ofile == false)
throw exception("file not open");
while (getline(text, line, '"'))
{
if (!line.find("/>"))
break;
seglist.push_back(line);
}
for (uint16_t i{}; i < seglist.size(); i++)
{
if (seglist[i-1] == " PhysicsMaterial=")
{
PhysicsMaterial = seglist[i];
return seglist[i];
}
}
line.clear();
seglist.clear();
}
catch (const std::exception& ex)
{
cout << "[ERROR]: " << ex.what() << endl;
return "[ERROR]";
}
}
string MatReader::getDiffuseLocation()
{
string line;
vector<string> seglist;
try
{
if (ofile == false)
throw exception("file not open");
while (getline(text, line, '"'))
{
seglist.push_back(line);
}
for (uint16_t i{}; i < seglist.size(); i++)
{
if (seglist[i - 1] == " File=")
{
PhysicsMaterial = seglist[i];
return seglist[i];
}
}
}
catch (const std::exception& ex)
{
cout << "[ERROR]: " << ex.what() << endl;
return "[ERROR]";
}
}
方法“getPhysMaterial()”和“getDiffuseLocation()”单独运行没有任何问题,但如果按顺序执行,它们会报错或根本不执行。
谢谢。
因此,首先您需要更正数组访问超出范围的问题。
您遇到的下一个问题是您需要重置流的位置以便从头重新读取它。
这是一个如何做到这一点的例子。
std::stringstream ss{ };
ss << "This is line one\n"
<< "This is line two\n"
<< "This is line three\n"
<< "This is line four\n";
// Points to the start of the stringstream.
// You can store this as a member of your class.
const std::stringstream::pos_type start{ ss.tellg( ) };
std::string line{ };
while ( std::getline( ss, line ) )
std::cout << line << '\n';
// Reset to the start of the stringstream.
ss.clear( );
ss.seekg( start );
while ( std::getline( ss, line ) )
std::cout << line << '\n';
我注意到的另一个问题是您正在检查循环条件中的 eof
。不要那样做.. Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())
) considered wrong?
改为执行以下操作:
std::stringstream ss{ };
if ( std::ifstream file{ "/Path/To/MyFile.txt" } )
{
std::string input{ };
while ( std::getline( file, input ) )
ss << input << '\n';
}
else
{
std::cerr << "Failed to open file\n";
return 1;
}
std::string line{ };
while ( std::getline( ss, line ) )
std::cout << line << '\n';
我编写了一个程序,它获取一个文件并将其读入 class 中的字符串流字段,现在我正尝试与它进行交互。问题是,当从几种方法中顺序读取时,其中一种方法会出错,或者根本不起作用。我想问题是我如何读取文件,我应该如何改进它?
有我的class:
class MatReader
{
protected:
...
stringstream text;
...
string PhysicsMaterial;
string Diffuse;
string NMap;
string Specular;
public:
/// <summary>
/// Read all lines in .mat document by string
/// </summary>
void ReadAllLines(string file_path);
/// <summary>
/// Getting PhysicsMaterial property
/// </summary>
string getPhysMaterial();
/// <summary>
/// Getting diffuse file path
/// </summary>
string getDiffuseLocation();
};
还有我的实现文件:
#include "MaterialHandler.h"
void MatReader::ReadAllLines(string mat_file)
{
ifstream infile(mat_file);
string str;
if (infile.is_open())
{
ofile = true;
while (!infile.eof())
{
getline(infile, str);
text << str+"\n";
}
}
else
throw exception("[ERROR] file does not exist or corrupted");
}
string MatReader::getPhysMaterial()
{
string line;
vector<string> seglist;
try
{
if (ofile == false)
throw exception("file not open");
while (getline(text, line, '"'))
{
if (!line.find("/>"))
break;
seglist.push_back(line);
}
for (uint16_t i{}; i < seglist.size(); i++)
{
if (seglist[i-1] == " PhysicsMaterial=")
{
PhysicsMaterial = seglist[i];
return seglist[i];
}
}
line.clear();
seglist.clear();
}
catch (const std::exception& ex)
{
cout << "[ERROR]: " << ex.what() << endl;
return "[ERROR]";
}
}
string MatReader::getDiffuseLocation()
{
string line;
vector<string> seglist;
try
{
if (ofile == false)
throw exception("file not open");
while (getline(text, line, '"'))
{
seglist.push_back(line);
}
for (uint16_t i{}; i < seglist.size(); i++)
{
if (seglist[i - 1] == " File=")
{
PhysicsMaterial = seglist[i];
return seglist[i];
}
}
}
catch (const std::exception& ex)
{
cout << "[ERROR]: " << ex.what() << endl;
return "[ERROR]";
}
}
方法“getPhysMaterial()”和“getDiffuseLocation()”单独运行没有任何问题,但如果按顺序执行,它们会报错或根本不执行。 谢谢。
因此,首先您需要更正数组访问超出范围的问题。 您遇到的下一个问题是您需要重置流的位置以便从头重新读取它。
这是一个如何做到这一点的例子。
std::stringstream ss{ };
ss << "This is line one\n"
<< "This is line two\n"
<< "This is line three\n"
<< "This is line four\n";
// Points to the start of the stringstream.
// You can store this as a member of your class.
const std::stringstream::pos_type start{ ss.tellg( ) };
std::string line{ };
while ( std::getline( ss, line ) )
std::cout << line << '\n';
// Reset to the start of the stringstream.
ss.clear( );
ss.seekg( start );
while ( std::getline( ss, line ) )
std::cout << line << '\n';
我注意到的另一个问题是您正在检查循环条件中的 eof
。不要那样做.. Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())
) considered wrong?
改为执行以下操作:
std::stringstream ss{ };
if ( std::ifstream file{ "/Path/To/MyFile.txt" } )
{
std::string input{ };
while ( std::getline( file, input ) )
ss << input << '\n';
}
else
{
std::cerr << "Failed to open file\n";
return 1;
}
std::string line{ };
while ( std::getline( ss, line ) )
std::cout << line << '\n';