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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了istringstream将字符串放回输入并再次读取相关的知识,希望对你有一定的参考价值。

所以我从文件中读出行,然后通过stringstream读出行。

我发现问题是因为线的格式很少将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有一个返回码是有原因的,当它是假的时候,这意味着putback失败了。

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

但是,您可以使用std::stringstream,而putback将以您希望的方式运行。

另一答案

我建议你的逻辑是错误的。你实际拥有的是固定字段格式,它不适用于istream提取操作符。

您最好阅读整行输入,然后通过列偏移提取“字段”。

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

不过,我想质疑你的意见。 istream字符串提取器operator>>(std::istream&, std::string&)将从输入流中提取一个空格分隔的标记。换句话说,你的第一次提取会拉开"126,"。所以剩下的逻辑完全错了。

以上是关于istringstream将字符串放回输入并再次读取的主要内容,如果未能解决你的问题,请参考以下文章

C++ 使用 istringstream 将整数读取为无符号字符

c++,istringstream sin(s),sin>>a>>b>>c,这个啥意思

C++中的 istringstream 的用法

在 C++ 中使用 istringstream 将字符串拆分为整数

如何将文件内容读入 istringstream?

使用 istringstream 丢失随机字符