C++ C++;:Linux代码在Windows上不起作用-将数据传输到程序

C++ C++;:Linux代码在Windows上不起作用-将数据传输到程序,c++,linux,windows,pipe,cat,C++,Linux,Windows,Pipe,Cat,我正在寻找一些帮助,将一个文件(16位有符号小端整数原始数据)从命令行传输到我的程序: cat rawdata.dat | myprogram 该代码在Linux上运行得很好,512字节每循环一次转换为256整数 如果我在Windows上用MinGW编译它,只有前76个值会正确转换。同时,程序在第一个while循环后停止 有人知道我做错了什么吗?我使用的是Windows7 64位+MinGW编译器 代码: #include <iostream> using namespace s

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

cat rawdata.dat | myprogram
该代码在Linux上运行得很好,512字节每循环一次转换为256整数

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

有人知道我做错了什么吗?我使用的是Windows7 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;
}
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
TL;博士:

修理?没有。您必须强制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;
}
返回的第一个值实际上位于位置358。不知道为什么

75:508:10870
76:510:9738
77:909:8225
78:911:11948
哇!看那个位置,从510跳到909。肮脏的510正好在缓冲区的末尾,但看起来缓冲区没有得到尊重

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

附录

托马斯·马修斯(Thomas Matthews)可能有一个正确的想法,即秘密窗口控制字符,但510是一个相当无害的逗号。为什么要为逗号发疯呢?

TL;博士:

修理?没有。您必须强制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;
}
返回的第一个值实际上位于位置358。不知道为什么

75:508:10870
76:510:9738
77:909:8225
78:911:11948
哇!看那个位置,从510跳到909。肮脏的510正好在缓冲区的末尾,但看起来缓冲区没有得到尊重

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

附录


托马斯·马修斯(Thomas Matthews)可能有一个正确的想法,即秘密窗口控制字符,但510是一个相当无害的逗号。为什么要为逗号发疯?

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

如果使用MinGW,只需在代码中添加以下行:

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

这一次终于解决了我的问题:

如果使用MinGW,只需在代码中添加以下行:

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

关于
而(!cin.eof())
。注意:在Windows中,二进制8位值0x1A(或26位小数)表示文件结束,除非您以“二进制”方式打开文件(即无翻译)。顺便说一句,二进制文件最好直接打开,而不是通过
cin
。就个人而言,我永远不会将二进制文件导入我的程序;太多事情可能会出错。关于
而(!cin.eof())
,请注意:在Windows中,二进制8位值0x1A(或26十进制)表示文件结束,除非您以“二进制”方式打开文件(即无翻译)。顺便说一句,二进制文件最好直接打开,而不是通过
cin
。就个人而言,我永远不会将二进制文件导入我的程序;太多的事情会出错。