【问题标题】:Piping a data file with cat to a C++ program使用 cat 将数据文件通过管道传输到 C++ 程序
【发布时间】:2015-10-08 21:30:57
【问题描述】:

我正在寻求一些帮助,将文件(16 位有符号小端整数原始数据)从命令行传输到我的程序:

cat data.dat | myprogram

然后它应该将数据转换为 16 位有符号整数。 它适用于前 12 个值。第 13 个值是错误的,后面是零。

第二个问题是程序似乎只进入了一次while循环。

我正在使用 Windows + MinGW。

我的代码:

#include <iostream>
using namespace std;

#define DEFAULT_BUF_LENGTH (16 * 16384)

int main(int argc, char* argv[]) 
{
    char buf[DEFAULT_BUF_LENGTH];

    while(cin >> buf) 
    {
        int16_t* data = (int16_t*) buf; //to int

        for(int i=0;i<18;i++)
        {
            cout << data[i] << endl;
        }
    }
    return 0;
}

输出:

0
9621
-14633
-264
5565
-12288
9527
-7109
11710
6351
4096
-5033
5773
147
0
0
0
0

感谢您的帮助!

【问题讨论】:

  • Piping for input/output的可能重复
  • 查看this 讨论。在 Windows 上 stdin 以文本模式打开,并且某些字节表示文件结束,解决方案是以二进制模式重新打开它。
  • 你不能使用&gt;&gt; 它转换行尾。您必须使用像cin.read() 这样的无格式输入 函数。 en.cppreference.com/w/cpp/io/basic_istream

标签: c++ pipe cat


【解决方案1】:

您可以尝试使用read() 而不是&gt;&gt; 运算符,后者通常用于格式化输入。检查实际读取了多少数据也很有用:

#include <iostream>
using namespace std;

#define DEFAULT_BUF_LENGTH (16 * 16384)

int main(int argc, char* argv[]) 
{
    char buf[DEFAULT_BUF_LENGTH];

    for(;;) 
    {
        cin.read(buf, sizeof(buf));
        int size = cin.gcount();
        if (size == 0) break;

        int16_t* data = (int16_t*) buf; //to int

        for(int i=0;i<size/sizeof(int16_t);i++)
        {
            cout << hex << data[i] << endl;
        }
    }
    return 0;
}

【讨论】:

  • 第二个问题仍然存在,程序只打印前 12 个值。我忘了提到我用g++ myprogram.cpp -static -o myprogram 编译我的程序。也许这就是原因?如果我在没有 -static 标志的情况下编译我的程序,它会在执行后崩溃(APPCRASH:错误模块名称:libstdc++-6.dll)。我没有找到解决这个问题的方法,但我认为它与 64 位 Windows 有关。在 Linux 上,您的代码按预期工作。
  • 拥有您的输入文件会很有用
  • 如果我不设置 -static 标志,即使是一个简单的 helloworld.cpp 程序也会崩溃。我认为我的 MinGW 坏了。我的问题与那个问题类似:[stackoverflow.com/questions/18157464/…windows\syswow64 中没有libstdc++.dll 我可以删除...
  • 我给你上传了一个测试文件:filedropper.com/rawdata你也用MinGW + 64bit Windows吗?
【解决方案2】:

声明cin &gt;&gt; buf 确实用数据填充整个buf。它只读取下一组非空白字符。 将cin &gt;&gt; buf 更改为read(0, buf, sizeof(buf)) &gt; 0

如果您坚持使用 C++ 流,请将循环的开头更改为:

while (!cin.eof()) {
    cin.read(buf, sizeof(buf));
    [...]

【讨论】:

  • 我同意这个诊断;那就是问题所在。我不相信建议的补救措施是最好的选择。当然,有一些方法可以从 cin 读取二进制数据,而不是使用像 read() 这样的 POSIX 文件描述符函数,这也需要 &lt;unistd.h&gt; 标头。
  • @JonathanLeffler:嗯,有时使用 ol' good C 更简单;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2016-06-11
  • 1970-01-01
  • 2011-08-09
  • 1970-01-01
相关资源
最近更新 更多