2017-07-15 90 views
1

作为一个noob C++项目,我正在构建一个依赖用户输入的游戏循环的CLI游戏。为了测试的目的,我希望能够将文件名作为命令行参数传递给程序,它将被视为“像标准输入”,直到它被读取。流对象代表文件输入,然后标准输入?

因此,我需要一种方法来封装代表一个文件的内容然后std::cin一旦该文件已被阅读过的对象 - 基本上前面加上一个文件的内容标准输入。至少,这似乎将是非常好的,让我能避免类似

std::istringstream retrieve_input(std::ifstream &file) { 
    std::string line; 
    if (std::getline(file, line)) 
    return std::istringstream{line}; 
    std::getline(std::cin, line); 
    return std::istringstream{line}; 
} 

与某种自定义类的一个好方法代替呢?或者我可以用std::cin搞砸我的文件内容吗?


澄清:我的游戏循环可能有20次迭代。如果我用五行传递一个文件,我想在游戏循环的前五个迭代中使用这五行,然后回到剩下的十五行的标准输入。我明白如何在一系列条件下做到这一点,但我认为在班级中必须有一种很好的方式来实现这种行为。我的问题是 - 它应该继承什么? std::streambuf?原则上这是一个好主意吗?

我(可能是坏的尝试)

class InputGrabber { 
public: 
    virtual std::istringstream retrieve_line() = 0; 
    virtual ~InputGrabber() {} 
}; 

class BaseInputGrabber : public InputGrabber { 
public: 
    BaseInputGrabber(std::istream &_in): in{_in} {} 
    std::istringstream retrieve_line() override { 
    std::string line; 
    std::getline(in, line); 
    return std::istringstream{line}; 
    } 

private: 
    std::istream ∈ 
}; 

class VarInputGrabber : public InputGrabber { 
public: 
    VarInputGrabber(std::istream &_in, const std::string &f_name) : 
    in{_in}, init{std::ifstream(f_name)} {} 
    std::istringstream retrieve_line() override { 
    std::string line; 
    if (std::getline(init, line)) { 
     return std::istringstream{line}; 
    } 
    std::getline(in, line); 
    return std::istringstream{line}; 
    } 
private: 
    std::istream ∈ 
    std::ifstream init; 
}; 
+1

@Ron不同意。一些标准库类意味着被继承。 'std :: streambuf'就是一个例子。 –

+1

@Ron你能区分“一些”和“全部”的概念吗? –

回答

2

将在下面的工作?您打开文件,重定向std::cin以从文件读取。在std::cin上使用std::getline,以便它从文件流中读取。在程序结束之前的一段时间,或者如果文件完成读取,将std::cin恢复到其原始状态。

#include <iostream> 
#include <fstream> 

int main(int argc, const char * argv[]) { 

    std::fstream file("https://stackoverflow.com/users/Brandon/Desktop/testingInput.txt", std::ios::in); 

    //Redirect cin to a file. 
    std::streambuf* cinBuffer = std::cin.rdbuf(); 
    std::cin.rdbuf(file.rdbuf()); 

    //Read line from std::cin (which points to the file) with std::getline. 
    std::string line; 
    std::getline(std::cin, line); 

    std::cout<<"INPUT LINE: "<<line<<std::endl; 

    //Redirect cin to standard input. 
    std::cin.rdbuf(cinBuffer); 

    //Read some line from the user's input.. 
    std::getline(std::cin, line); 
    std::cout<<"USER INPUT LINE: "<<line<<std::endl; 
    std::cin.get(); 

    return 0; 
} 
-3

是下面的例子,你在找什么?

std::string readNextLine(std::istream& is) 
{ 
    std::string line; 

    if(!std::getline(is, line)) 
     std::getline(std::cin, line); 

    return line; 
} 

int main() 
{ 
    std::stringstream ss ("a\nb\nc\n"); 

    for(int i = 0; i < 5; ++i) 
    { 
     auto line = readNextLine(ss); 

     std::cout << "got: " << line << std::endl; 
    } 

    return 0; 
} 

stringstream可以用fstream或任何其他实现std :: istream的类型替换。

你可以在这里进行测试http://cpp.sh/5iv65

+0

谢谢,但我认为这实际上是我有的第一个功能,除非你没有传递'std :: cin'的引用。 –

+0

好吧,你是对的。可能是你搜索这样的解决方案https://stackoverflow.com/questions/19506444/composite-stdistream-in-c? –

+0

是的,看起来很有希望,我会看看,谢谢! –

-2

您可以随时通过argv从文件重定向。从一开始就把整个事情当作std :: cin来处理。

相关问题