如何将istringstream和ifstream分配给istream变量

How to assign istringstream and ifstream to an istream variable?

本文关键字:分配 istream 变量 ifstream istringstream      更新时间:2023-10-16

我想要一个类型为istream的变量,它可以容纳文件或字符串的内容。其想法是,如果没有指定文件,则类型为istream的变量将被分配一个字符串。

std::ifstream file(this->_path)

std::istringstream iss(stringSomething);

std::istream is

我尝试过将它们分配给istream变量,就像处理从同一基类继承的其他对象一样,但没有成功。

如何将istringstreamifstream分配给istream变量?

基类指针可以指向派生类数据。std::istringstreamstd::ifstream都来源于std::istream,所以我们可以做:
//Note that std::unique_ptr is better that raw pointers
std::unique_ptr<std::istream> stream;
//stream holds a file stream
stream = std::make_unique<std::ifstream>(std::ifstream{ this->_path });
//stream holds a string
stream = std::make_unique<std::istringstream>(std::istringstream{});

现在你只需要使用提取内容

std::string s;
(*stream) >> s;

不能分配给std::istream,但可以绑定到这样的引用:

#include <string>
#include <sstream>
#include <fstream>
#include <iostream>
std::istringstream test_data(R"~(
some test data here
instead of in an external
file.
)~");
int main(int, char* argv[])
{
    // if we have a parameter use it
    std::string filename = argv[1] ? argv[1] : "";
    std::ifstream ifs;
    // try to open a file if we have a filename
    if(!filename.empty())
        ifs.open(filename);
    // This will ONLY fail if we tried to open a file
    // because the filename was not empty    
    if(!ifs)
    {
        std::cerr << "Error opening file: " << filename << 'n';
        return EXIT_FAILURE;
    }
    // if we have an open file bind to it else bind to test_data
    std::istream& is = ifs.is_open() ? static_cast<std::istream&>(ifs) : test_data;
    // use is here
    for(std::string word; is >> word;)
    {
        std::reverse(word.begin(), word.end());
        std::cout << word << 'n';
    }
}

从标准库中取出一页:不要赋值;指定引用。这可能就是你想要的。

std::istringstream iss(stringSomething);
std::istream& input(iss);

由于流携带大量状态,因此复制它们充满了语义问题。例如,考虑tellg在原始调用seekg后应在副本中报告的内容。相比之下,参考文献透明地回答了这个问题。

在C++中,即使Child继承自Parent,也不能将Child类型的对象分配给Parent类型的变量。但是,您可以将Child类型的指针分配给Parent类型的指针。您可能需要考虑动态分配对象。

在C++中

std::istream is;

是一个实际对象,分配给它将调用复制分配运算符,该运算符将iss的子对象(std::istream(复制到is中并对其进行切片。LogicStuff链接的示例将显示您需要为iss分配一个引用或指针,如so:

std::istream &is_ref = iss;

值、引用和指针之间的差异是C++的基础,我建议你要牢牢掌握它们。

std::istream可以由std::streambuf(基本上是产生或消耗字符的设备(构建。所有CCD_ 18对象都有一个相关的CCD_。

std::ifstream file(this->_path); 
std::istringstream iss("str in gSo met hing");
std::istream A(iss.rdbuf());   // shares the same buffer device with iss
std::string str;
//////////////
while(A >> str) std::cout << str << " | "; //read everything from stream (~> iss)
std::cout << std::endl;
A = std::move(file);
while(A >> str) std::cout << str << " | "; //read from file, using same stream (~> file)