【问题标题】:stringstream only works for one line then breaks when reusedstringstream 仅适用于一行,然后在重用时中断
【发布时间】:2026-01-20 05:25:01
【问题描述】:

我正在尝试读取一个名为 trajectory.txt 的简单文件(如下所示),如下所示:

true true false
2

我的代码很简单,读入前两行并将其存储在一些变量中。

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

int main(int argc, char** argv)
{

int num_waypoints=0;
bool pos=1, vel=0, acc=0;
std::ifstream file;
std::string filename = "trajectory.txt";
file.open(filename.c_str());
std::string line;

// Read first 2 lines
if (std::getline(file, line)) {

  //sstream for each line
  std::stringstream ss(line);

  //first line
  std::string pos_str, vel_str, acc_str;
  ss >> pos_str >> vel_str >> acc_str;

  //evaluate
  (pos_str == "true" ? pos = true : pos = false);
  (vel_str == "true" ? vel = true : vel = false);
  (acc_str == "true" ? acc = true : acc = false);

  //second line
  if (std::getline(file, line)) {               //GDB confirms, line == "2"
    std::string num_waypoints_str;              
    ss >> num_waypoints_str;                    //THIS DOES NOTHING?
    num_waypoints = stoi(num_waypoints_str);
}

} //main()

问题是在倒数第二行,num_waypoints_str 在字符串流应该读入值之后被留空。

使用 GDB,我能够确认 stringstream 确实具有“2”的值,但将值指向 num_waypoints_str 似乎存在问题。

因此我只有两个问题:

  1. 为什么字符串流不将其值传递给字符串? (是否与进入新范围有关)
  2. 能否将我的代码简化为直接从字符串流输入第 1 行到布尔值 pos,或者我必须通过评估字符串的值将字符串 pos_str 转换为 pos

我正在通过g++ -g -std=c++11 main.cpp -o main 编译。请尝试复制我的问题。我觉得我错过了一些简单的东西。

【问题讨论】:

  • " GDB 确认,行 == "2" ",但 line != ss。流ss 包含您传递给构造函数的行,您从中读取第一行,但之后您不会更改ss 的内容,但希望它包含更多行(您通过getline 读取但不进入ss)
  • 如果你想让ss包含新行,你必须给它:ss.str(line)。它不会读懂你的想法并复制自己。

标签: c++ c++11 io getline stringstream


【解决方案1】:

字符串流不会神奇地绑定到您的std::string line;

   //second line
   if (std::getline(file, line)) {               //GDB confirms, line == "2"
     std::string num_waypoints_str;              
     ss >> num_waypoints_str;                    //THIS DOES NOTHING?
     num_waypoints = stoi(num_waypoints_str);

ss 仍然具有在构造函数中设置的值。更准确地说:

std::stringstream 的constructor 会复制你给它的字符串,它不会绑定到它。

如果您不想构建另一个,可以使用std::basic_stringstream::str 更新 ss 的内容。 注意:像其他流一样,字符串流也有标志,例如 eof,这些也需要重置。所以在你的情况下:

    ss.clear();
    ss.str(line);

【讨论】:

  • 添加ss.str(line) 开始最后一个代码块对我没有任何作用。我也尝试调用ss.str(std::string()) 来清除没有结果的字符串流
  • @Max 对不起,我已经对我的回答进行了澄清!
【解决方案2】:

非常接近答案。您还需要在重用它之前清除字符串流。

//first use
getline(file, line);
stringstream ss(line);
ss.clear()

//second use
getline(file, line);
ss.str(line);

【讨论】:

    最近更新 更多