从 C++ 中的标准输入或文件透明读取?
Transparent read from stdin or a file in C++?
我想解析 stdin
流或文件。所以我想要一个 function/method 来接受其中任何一个。
请注意,我的目标不是调用 read
两次!
因为 istream
是 cin and
ifstream 的基础 class 我应该可以这样写:
#include <iostream>
#include <fstream>
void read(std::istream &fp) {
while(!fp.eof()) {
std::string line;
std::getline(fp, line);
std::cout << line << std::endl;;
}
}
int main(int argc, char *argv[])
{
std::ifstream fp;
if (argc >= 2) {
fp.open(argv[1]);
if (!fp) abort();
}
else {
fp = std::cin;
}
read(fp);
if (fp.is_open()) {
fp.close();
}
return 0;
}
在 C 中,我可以使用 read_content(stdin)
或 read_content(fp)
调用它来执行以下操作:
void read_content(FILE *file)
在 C++ 中执行此操作的正确方法是什么?
In C I can do the following with calling it with either read_content(stdin) or read_content(fp):
是的,在 C++ 中,您应该只调用 read(std::cin)
或 read(fp)
。一模一样
行
fp = std::cin;
是错误的做法,因为 std::cin
仅声明为 std::istream
。没有采用 istream 的 std::ifstream
构造函数,无论如何你都不想要一个独立的对象,如果 std::cin
确实是从 std::ifstream
派生的某种类型的对象,你会切片它。
std::cin
是 std::istream
的一个实例,而不是从 std::ifstream
派生的,但恰恰相反。
基于Stream的继承图I/O:
(摘自cppreference.com - Input/output library)
因此,可以使用指向 std::istream
的引用或指针来执行 OP 意图。
演示:
#include <iostream>
#include <fstream>
void read(std::istream &fp) {
while(!fp.eof()) {
std::string line;
std::getline(fp, line);
std::cout << line << std::endl;;
}
}
int main(int argc, char *argv[])
{
std::ifstream fp;
std::istream &in = (argc >= 2)
? [&]() -> std::istream& {
fp.open(argv[1]);
if (!fp) abort();
return fp;
}()
: std::cin;
read(in);
if (fp.is_open()) {
fp.close();
}
return 0;
}
注:
while (!fp.eof()) {
应替换为
while (fp) {
其原因已在
中进行了彻底讨论
SO: Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())
) considered wrong?.
我想解析 stdin
流或文件。所以我想要一个 function/method 来接受其中任何一个。
请注意,我的目标不是调用 read
两次!
因为 istream
是 cin and
ifstream 的基础 class 我应该可以这样写:
#include <iostream>
#include <fstream>
void read(std::istream &fp) {
while(!fp.eof()) {
std::string line;
std::getline(fp, line);
std::cout << line << std::endl;;
}
}
int main(int argc, char *argv[])
{
std::ifstream fp;
if (argc >= 2) {
fp.open(argv[1]);
if (!fp) abort();
}
else {
fp = std::cin;
}
read(fp);
if (fp.is_open()) {
fp.close();
}
return 0;
}
在 C 中,我可以使用 read_content(stdin)
或 read_content(fp)
调用它来执行以下操作:
void read_content(FILE *file)
在 C++ 中执行此操作的正确方法是什么?
In C I can do the following with calling it with either read_content(stdin) or read_content(fp):
是的,在 C++ 中,您应该只调用 read(std::cin)
或 read(fp)
。一模一样
行
fp = std::cin;
是错误的做法,因为 std::cin
仅声明为 std::istream
。没有采用 istream 的 std::ifstream
构造函数,无论如何你都不想要一个独立的对象,如果 std::cin
确实是从 std::ifstream
派生的某种类型的对象,你会切片它。
std::cin
是 std::istream
的一个实例,而不是从 std::ifstream
派生的,但恰恰相反。
基于Stream的继承图I/O:
(摘自cppreference.com - Input/output library)
因此,可以使用指向 std::istream
的引用或指针来执行 OP 意图。
演示:
#include <iostream>
#include <fstream>
void read(std::istream &fp) {
while(!fp.eof()) {
std::string line;
std::getline(fp, line);
std::cout << line << std::endl;;
}
}
int main(int argc, char *argv[])
{
std::ifstream fp;
std::istream &in = (argc >= 2)
? [&]() -> std::istream& {
fp.open(argv[1]);
if (!fp) abort();
return fp;
}()
: std::cin;
read(in);
if (fp.is_open()) {
fp.close();
}
return 0;
}
注:
while (!fp.eof()) {
应替换为
while (fp) {
其原因已在
中进行了彻底讨论
SO: Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())
) considered wrong?.