C ++:Linux代码在Windows上不起作用 - 管道数据到程序

时间:2015-07-24 23:29:01

标签: c++ linux windows pipe cat

我正在寻找一些帮助从命令行管道文件(16位带符号的小端整数原始数据)到我的程序:

cat rawdata.dat | myprogram

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

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

有人知道我做错了什么吗?我使用的是Windows 7 64位+ 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

2 个答案:

答案 0 :(得分:0)

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

的Wooo-EEE!看看那个位置从510跳到909.令人讨厌。 510就在缓冲区的末尾,但它看起来并不像缓冲区那样。

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

附录

托马斯马修斯可能有正确的想法,秘密的Windows控制角色,但510是一个相当无害的逗号。为什么要用逗号来疯狂?

答案 1 :(得分:0)

This one finally solved my problem:

Read binary data from std::cin

Just add the following lines to your code if you are using MinGW:

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