【问题标题】:C ++ string stream issue: getline doesn't work with stringstreamC++ 字符串流问题:getline 不适用于 stringstream
【发布时间】:2021-04-07 20:17:34
【问题描述】:

我编写了一个程序,它获取一个文件并将其读入类中的 stringstream 字段,现在我正在尝试与它进行交互。问题是,当从几种方法中顺序读取时,其中一种方法会出错,或者根本不起作用。我想问题是我如何读取文件,我应该如何改进它?

还有我的课:

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()”单独工作没有任何问题,但如果它们按顺序执行,它们会出错或根本不执行。 谢谢。

【问题讨论】:

  • seglist[i-1] 将在第一次迭代时越界访问(当 i 为 0 时)。
  • 正如@1201ProgramAlarm 所指出的,当i0 时,您没有处理循环的第一次迭代。此外,告诉人们您收到的 error 的内容会很有帮助。
  • 另外,您不会重置内部 std::stringstream 指针(它会跟踪您消耗了多少)。这就是为什么当你顺序调用每个方法时它不起作用的原因。
  • @1201ProgramAlarm 是的,非常感谢我会解决这个问题,但这并不能解决问题。如果我只是删除数组输出 - 它仍然不起作用,我问的是字符串流的问题,而不是数组输出。
  • @WBuck 哦,好吧...谢谢,我怎样才能重置字符串流指针? seekp(0) 对我不起作用。

标签: c++ getline stringstream


【解决方案1】:

因此,首先您需要纠正超出范围的数组访问问题。 您遇到的下一个问题是您需要重置流的位置以便从头开始重新读取它。

这是一个示例,说明如何做到这一点。

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'; 

【讨论】:

    猜你喜欢
    • 2012-08-24
    • 2013-04-28
    • 2020-06-18
    • 2017-09-28
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2016-06-28
    相关资源
    最近更新 更多