Мне нужна помощь в передаче файла (необработанных данных с 16-разрядными знаковыми младшими целыми числами) из командной строки в мою программу:
cat rawdata.dat | myprogram
Код работает очень хорошо в Linux, 512 байт преобразуются в 256 дюймов за цикл.
Если я скомпилирую его с MinGW в Windows, только первые 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;
}
TestFile: 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
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-еее! Посмотрите на эту позицию, прыгайте с 510 до 909. Противно. 510 будет прямо в конце буфера, но не похоже, чтобы буфер соблюдался.
Насколько я понимаю, istream :: read должен быть полностью неформатированным, просто тупой копией входного потока в предоставленный буфер, поэтому я понятия не имею, почему это происходит. Может быть, окна просто странно.
добавление
Томас Мэтьюз, вероятно, имеет правильную идею, секретные символы управления Windows, но 510 — довольно безобидная запятая. Зачем сходить с ума через запятую?
Этот наконец решил мою проблему:
Чтение двоичных данных из std :: cin
Просто добавьте следующие строки в ваш код, если вы используете MinGW:
#include <io.h>
#include <fcntl.h>
#include <fstream>
_setmode(_fileno(stdin), _O_BINARY);