【问题标题】:C++: Linux code does not work on Windows - piping data to programC++:Linux 代码在 Windows 上不起作用 - 将数据传送到程序中
【发布时间】:2015-10-15 18:14:14
【问题描述】:

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

cat rawdata.dat | myprogram

代码在 Linux 上运行良好,每循环 512 个字节转换为 256 个整数。

如果我在 Windows 上使用 MinGW 编译它,只有前 76 个值会被正确转换。程序也会在第一个 while 循环后停止。

有人知道我做错了什么吗?我正在使用 Windows 7 64bit + MinGW 编译器。

代码:

#include <iostream>

using namespace std;

int main() 
{
    int BUF_LEN = 512;
    char buf[BUF_LEN];

    while(!cin.eof()) 
    {
        cin.read(buf, BUF_LEN);
        int16_t* data = (int16_t*) buf; //to int

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

测试文件: http://www.filedropper.com/rawdata

正确的值是:

70   -11584
71   13452
72   -13210
73   -13331
74   13893
75   10870
76   9738
77   6689
78   -253
79   -1009
80   -16036
81   14253
82   -13872
83   10020
84   -5971

【问题讨论】:

  • 关于while(!cin.eof())give this link a read
  • 注意:在 Windows 中,二进制 8 位值 0x1A(或十进制 26)表示文件结束,除非您以“二进制”形式打开文件(即没有翻译)。
  • 顺便说一句,二进制文件最好直接打开,而不是通过cin。就个人而言,我永远不会将二进制文件通过管道传输到我的程序中。太多的事情可能会出错。

标签: c++ linux windows pipe cat


【解决方案1】:

TL;DR:

修复?没有一个。您必须强制 cin 进入二进制模式。我认为要做到这一点,您必须关闭并重新打开 cin,而我只能看到结局很糟糕。

真正的解决方案是不要这样做。用

正常打开文件
std::ifstream in("rawdata.dat", std::fstream::binary);

故事的其余部分:

怀疑这将是某种笨拙的二进制翻译,所以我整理了一些代码来看看文件中发生了什么。

#include <iostream>
#include <fstream>

using namespace std;

#define BUF_LEN 512

int main()
{
    ifstream in("rawdata.dat");
    char buf[BUF_LEN];
    int16_t test;
    int count = 0;
    while(in.read((char *)&test, sizeof(test)))
    {
        cout << count++ << ":" << in.tellg() << ":" << test << endl;
        if (count == 85)
        {
            break;
        }
    }
    return 0;
}

重要输出(int16 数字:文件中的位置:读取的数字

0:358:0

返回的第一个值实际上是在位置 358。不知道为什么。

75:508:10870
76:510:9738
77:909:8225
78:911:11948

哇哦!看看那个位置从 510 跳到 909。讨厌。 510 就在缓冲区的末尾附近,但看起来缓冲区并没有受到尊重。

我的理解是 istream::read 应该是完全未格式化的,只是输入流的一个哑副本到提供的缓冲区,所以我不知道为什么会发生这种情况。也许窗户很奇怪。

附录

Thomas Matthews 可能有正确的想法,秘密 Windows 控制字符,但 510 是一个相当无害的逗号。为什么要疯狂地使用逗号?

【讨论】:

    【解决方案2】:

    这个终于解决了我的问题:

    Read binary data from std::cin

    如果您使用的是 MinGW,只需将以下行添加到您的代码中:

    #include <io.h>
    #include <fcntl.h>
    #include <fstream>
    _setmode(_fileno(stdin), _O_BINARY);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 2015-10-14
      相关资源
      最近更新 更多