cin.tellg 从管道接收输入时返回 -1
Posted
技术标签:
【中文标题】cin.tellg 从管道接收输入时返回 -1【英文标题】:cin.tellg returns -1 when receiving input from a pipe 【发布时间】:2018-12-30 21:17:49 【问题描述】:我有一种情况需要将子进程的输出通过管道传输到ifstream
。
我正在尝试使用以下方法从文件描述符创建 ifstream:How to construct a c++ fstream from a POSIX file descriptor?
我也尝试使用从子标准错误到我自己的标准输入的管道,并使用 cin 作为我的流。
在这两种情况下,当我调用 tellg 时,我都会得到 -1。
这是我的代码,其中包含从子标准错误到父标准输入的管道:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;
int
main()
int mypipe[2];
pipe(mypipe);
dup2(mypipe[0], STDIN_FILENO);
dup2(mypipe[1], STDERR_FILENO);
__pid_t pid = fork();
if(pid == 0)
// this is a process that outputs stuff into std::err
char* argv[] = "copy-feats", nullptr;
int ret = execvp(argv[0], argv);
exit(ret);
int status;
waitpid(pid, &status, WNOHANG);
cin.clear(); // attempting to clear the error state. Not working.
long size = cin.tellg();
cout << size << endl;
正如我所说,tellg 的输出是 -1。
我想如果我尝试使用 getline(cin, some_string) 我实际上可以看到子程序的输出。
我尝试从管道创建流,但它仍然给我 -1。
这是我使用的代码:
#include <iostream>
#include <fstream>
#include <ext/stdio_filebuf.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#define READ_FD 0
#define WRITE_FD 1
using namespace std;
using FilebufType = __gnu_cxx::stdio_filebuf<std::ifstream::char_type>;
int
main()
int mypipe[2];
pipe(mypipe);
__pid_t pid = fork();
if(pid == 0)
dup2(mypipe[WRITE_FD], STDERR_FILENO);
char* argv[] = "copy-feats", nullptr;
int ret = execvp(argv[0], argv);
exit(ret);
int status;
waitpid(pid, &status, WNOHANG);
FilebufType filebuf(mypipe[READ_FD], std::ios::in);
istream is(&filebuf);
is.clear();
auto size = is.tellg();
cout << size << endl;
提前致谢。
【问题讨论】:
当然你从tellg()
得到-1。管道是不可搜索的,当涉及到管道时,没有“文件位置”之类的东西。只有实际的物理文件是物理的,并提供文件位置。只有std::ifstream
s 在附加到真实文件时提供文件位置指示。
查看返回值的含义。
@SamVarshavchik 谢谢你回答了我的问题。我建议您将其发布为答案,以使未来的访问者更清楚。
【参考方案1】:
实际上tellg()
仅在输入流是真实文件时才返回实际文件位置。也就是说,当输入流是std::ifstream
时,只有当底层文件是普通文件时。
管道和其他非普通文件没有文件位置的概念。
在您使用的 Linux 上,tellg()
通常是通过使用 lseek(2)
实现的(间接地,但在此不相关),lseek(2)
's documentation 明确指定如果文件描述符返回 ESPIPE
错误是一个管道。最终,错误返回将转换为 tellg()
返回 -1。
【讨论】:
以上是关于cin.tellg 从管道接收输入时返回 -1的主要内容,如果未能解决你的问题,请参考以下文章
在 Kiosk 模式下配置时,是不是可以从 HoloLens 2 中的门户接收虚拟输入