istringstream将字符串放回输入并再次读取

istringstream put string back on input and read again

本文关键字:读取 输入 字符串 istringstream      更新时间:2023-10-16

所以我从文件中读出行,然后通过字符串流读出行。

我发现的问题在于,由于该行的格式,很少将 2 个单独的部分写在一起并作为一个字符串一起阅读。我试图通过将错误的读取值放回流中并再次读取来解决此问题,但看起来 istringstream 不在乎我把字符放回原处。他们只是不再被读出来。

在这里,问题崩溃了。S1 是一个很好的字符串。S2解决了评论中错误阅读的问题:

总之。是否可以将字符串放回 istringstream 并在下一个操作中读取它?

#include <sstream>
#include <string>
#include <vector>

int main()
{
    std::string device_id;              //126, I_VS_MainVoltageAvailabl
    std::string ea_type;                //E
    std::string address;                //0.1
    std::string data_type;              //BOOL
    std::vector<std::string> comment;   //VS - Steuerspannung vorhanden / Main voltage available"
    std::string s1 = "126,I_Btn_function_stop     E       1.2 BOOL      Taster Stopp Funktion / Button Stop Function";
    std::string s2 = "126,I_VS_MainVoltageAvailablE       0.1 BOOL      VS - Steuerspannung vorhanden / Main voltage available";
    std::istringstream ist{ s2 };
    ist >> device_id;                   // Read 126, I_VS_MainVoltageAvailablE    the E should be read in ea_type
    ist >> ea_type;                     // 0.1
    //my idea
    if (!ea_type.empty() && isdigit(static_cast<unsigned char>(ea_type[0]))) {  //first is a digit so already next was read
        for (const auto& x : ea_type)       //Try to put 0.1 in the stream
            ist.putback(x);
        ea_type = device_id[device_id.size() - 1];      // = "E"
        device_id.pop_back();                           // = "126, I_VS_MainVoltageAvailabl"
    }
    ist >> address;                                     // Expected "0.1" instead  "BOOL" why 0.1 was putback on the stream???
    ist >> data_type;
    for (std::string in; ist >> in;)
        comment.push_back(in);
}

像往常一样,人们忽略了返回代码。 putback有一个返回代码是有原因的,当它为 false 时,表示putback失败。

特别是,std::istringstream输入字符串流,因此是仅输入流。因此,您不能在其上使用putback,它总是会失败。

但是,您可以改用std::stringstream,这样putback就会按照您想要的方式运行。

我建议你的逻辑格式不正确。您实际拥有的是一种固定的字段格式,不适合 istream 提取运算符。

您最好读取整行输入,然后按列偏移量提取"字段"。

或者,一次读取一个字节,附加到要提取的字符串变量,直到读取足够的字节来填充它。也就是说,将 29 个字节读入 device_id,然后将多少字节(1?8?(字节读入ea_type,依此类推。

不过,我想质疑你的评论。istream 字符串提取器operator>>(std::istream&, std::string&)将从输入流中提取一个空格分隔的令牌。换句话说,您的第一次提取会拉"126,"。所以其余的逻辑是完全错误的。