C ++ Read Binary файл, содержащий числа типа double - PullRequest
0 голосов
/ 28 июня 2011

У меня есть двоичный файл, который содержит числа типа double.
Пример входного файла доступен здесь: www.bobdanani.net/download/A.0.0
Я хочу прочитать файл и распечататьцифры в нем.Вот что я сделал:

char* buffer;
int length;
string filename = "A.0.0";
ifs.open (filename.c_str(), ios::in | ios::binary);
// get length of file:
ifs.seekg (0, ios::end);
length = ifs.tellg();
ifs.seekg (0, ios::beg);
// allocate memory:
buffer = new char [length];
// read data as a block:
ifs.read (buffer,length);
ifs.close();

cout.write (buffer,length);
cout << buffer << endl;

delete[] buffer;

Я также пытался использовать приведение типов к удвоению при печати числа, но я получил странные символы.Каков наилучший способ сделать это?Мне нужны данные этого двоичного файла в качестве входных данных для функции для параллельной программы.Но это выходит за рамки этого вопроса.

Ответы [ 3 ]

3 голосов
/ 28 июня 2011

Хотя я могу ошибаться, так как вы сказали, что число разделено табуляцией / пробелом, я готов быть на самом деле это ASCII-данные, а не необработанные двоичные данные.Поэтому лучший способ работы со значением с плавающей запятой - использовать operator>> для объекта ifstream, а затем вставить его в double.Это сделает автоматическое преобразование входного значения в двойное, где то, что вы сделали, будет просто копировать символьные байты, которые составляют значение с плавающей запятой, но сами по себе не являются значением с плавающей запятой.Кроме того, если вы пытаетесь вывести свой буфер как строку, вы явно не завершаете его нулем, поэтому он будет продолжать считывать стек до тех пор, пока он не встретит нулевой терминатор или вы не получите ошибку сегментации из-за доступа к памятиОС не позволяет вам получить доступ с вершины стека.Но в любом случае, в конце концов, ваш буфер не будет представлением типа данных double.

Так что у вас будет что-то вроде:

double my_double_val;

ifs.open (filename.c_str());

if (ifs)
{
    ifs >> my_double_val;
}
else
{
    cerr << "Error opening file" << endl;
}

ifs.close();

cout << "Double floating point value: " << my_double_val << endl;
0 голосов
/ 17 июля 2011

Используйте вызов системной функции в C ++ (при условии, что вы используете ОС Unix) и передайте 'od -e filename' в качестве аргумента вызова системной функции. И тогда вы можете легко передать значения, которые он вернул, и прочитать их. Это один из подходов. Конечно, есть много других подходов для этого.

0 голосов
/ 28 июня 2011
cout.write (buffer,length);

Не делай этого! Выше приведен вывод двоичных данных на стандартный вывод.

cout << buffer << endl;

Не делай этого тоже! Вышеприведенное будет выводить двоичные данные до первого байта, который оказывается нулевым для стандартного вывода. Если такого байта нет, он будет продолжать проходить через конец буфера (так что неопределенное поведение).

Если буфер действительно содержит удваивается и только удваивается, вы можете сделать что-то противное, как

double * dbuf = reinterpret_cast<double*>(buffer);
int dlength = length / sizeof(double);
...