C++:Linux 代码不适用于 Windows - 管道数据到程序
C++: Linux code does not work on Windows - piping data to program
我正在寻找从命令行向我的程序传输文件(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
长话短说:
修复?没有一个。您必须强制 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 number:position in file:number read
0:358:0
返回的第一个值实际上在位置 358。不知道为什么。
75:508:10870
76:510:9738
77:909:8225
78:911:11948
呜呜呜!看看那个位置从 510 跳到 909。讨厌。 510 就在缓冲区的末尾附近,但看起来缓冲区并没有受到尊重。
我的理解是 istream::read 应该是完全未格式化的,只是提供缓冲区的输入流的哑副本,所以我不知道为什么会这样。也许 windows 很奇怪。
附录
Thomas Matthews 可能有正确的想法,秘密 Windows 控制字符,但 510 是一个相当无害的逗号。为什么要为逗号疯狂?
这个终于解决了我的问题:
Read binary data from std::cin
如果您使用的是 MinGW,只需将以下行添加到您的代码中:
#include <io.h>
#include <fcntl.h>
#include <fstream>
_setmode(_fileno(stdin), _O_BINARY);
我正在寻找从命令行向我的程序传输文件(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
长话短说:
修复?没有一个。您必须强制 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 number:position in file:number read
0:358:0
返回的第一个值实际上在位置 358。不知道为什么。
75:508:10870
76:510:9738
77:909:8225
78:911:11948
呜呜呜!看看那个位置从 510 跳到 909。讨厌。 510 就在缓冲区的末尾附近,但看起来缓冲区并没有受到尊重。
我的理解是 istream::read 应该是完全未格式化的,只是提供缓冲区的输入流的哑副本,所以我不知道为什么会这样。也许 windows 很奇怪。
附录
Thomas Matthews 可能有正确的想法,秘密 Windows 控制字符,但 510 是一个相当无害的逗号。为什么要为逗号疯狂?
这个终于解决了我的问题:
Read binary data from std::cin
如果您使用的是 MinGW,只需将以下行添加到您的代码中:
#include <io.h>
#include <fcntl.h>
#include <fstream>
_setmode(_fileno(stdin), _O_BINARY);