2013-11-14 2 views
0

У меня есть-структура:C++ двоичного файла Структура функции

struct zipType{ 
    int postalCode; 
    double longitude; 
    double latitude; 
    }; 

И у меня есть функция под названием zipToCout:

void zipToCout(zipType zip){ 
    cout << "Postal Code = " << zip.postalCode << "\tLongitude = " << zip.longitude << "\t\tLatitude = " << zip.latitude << endl; 
    } 

теперь нужна функция, чтобы прочитать двоичный файл в zipType структуру , Предполагается, что прототипом функции будет void binRead(zipType *zip, fstream *input);. Единственный способ, которым я могу приблизиться к этому, - изменить прототип на этот void binRead(zipType &zip, fstream &input). При этом, вот что я в настоящее время для функции:

void binRead(zipType &zip, fstream &input){ 
    int temp; 
    double temp2; 
    zipType tempZip; 
    tempZip = zip; 
    //cout << "Reader at location " << input.tellg() << endl; 
    input.read((char*)&temp,sizeof(int)); 
    tempZip.postalCode=temp; 
    input.read((char*)&temp2,sizeof(double)); 
    tempZip.longitude=temp2; 
    input.read((char*)&temp2,sizeof(double)); 
    tempZip.latitude=temp2; 
    zipToCout(tempZip); 
    } 

Это выход я получаю, когда я бегу это на моем sample.bin файле:

Postal Code = 64501  Longitude = 2.61457e-261    Latitude = -7.13357e+288 

Что мне нужна помощь в переформатирование функции для использования * вместо & и исправление того, как правильно прочитать файл в трех переменных. Спасибо, что посмотрели! Кроме того, я должен прочитать только один zipType из файла на этом этапе.

+0

Когда вы использовали 'zipType *', вы также использовали '->' вместо '.' для доступа к членам структуры? –

ответ

0
void binRead(zipType *zip, fstream *input) 
{ 
    input->read((char*)(&zip->postalCode), sizeof(int )); 
    input->read((char*)(&zip->longitude ), sizeof(double)); 
    input->read((char*)(&zip->latitude ), sizeof(double)); 
    zipToCout(*zip); 
} 

Кроме того, в зависимости от архитектуры (то есть 32-битный x86.), Следующие могут работы:

void binRead(zipType *zip, fstream *input) 
{ 
    input->read((char*) zip, sizeof(zipType)); 
    zipToCout(*zip); 
} 

Это будет работать только на архитектурах, где double только требует выравнивания 4-байтовый , Я считаю, 32-бит x86 подходит для этого. Быстрый тест, который я написал на местном уровне, говорит о том, что это так.

Быстрое примечание о переносимом, обслуживаемом коде, который выходит за рамки непосредственной необходимости выше: Код, такой как приведенный выше, работает достаточно хорошо, когда машина, сохраняющая данные, такая же, как машина, которая позже считывает данные. Это, однако, приводит к проблемам с переносимостью. Если вы действительно хотите создать формат файла, который переносится на разных машинах и сохраняет данные, вышеупомянутые методы на самом деле не способствуют этому.

+0

Это работает потрясающе. Я почти что раньше, но не смог понять синтаксис, я почему-то пытался «ввести .-> прочитать». Приветствую человека! У меня все еще есть распечатка 'Longitude = 2.61457e-261 Latitude = -7.13357e + 288'. Это нормально? – user2990286

+0

Это похоже на фиктивные координаты. Но, по крайней мере, это не изменение от того, что у вас было до этого. Насколько велик ваш входной файл .bin? Если это 24 байта, то вам, вероятно, нужно будет есть 4 байта пэда между вашими «int» и «double». (Не сложно сделать.) Если это всего 20 байт, то я не уверен, в чем проблема. –

+0

Кроме того, меня будет интересовать то, что вы можете сказать о проблемах переносимости, которые могут быть вызваны, я все о кодировании наилучшим образом. – user2990286

0

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

void binRead(zipType &zip, fstream &input){ 
    char* temp = NULL 
    char* temp2 = NULL; 
    zipType tempZip; 
    tempZip = zip; 
    //cout << "Reader at location " << input.tellg() << endl; 
    input.read(temp,sizeof(int)); 
    tempZip.postalCode=(atoi)temp; //use for proper conversion, or other function 
    input.read(temp2,sizeof(double)); 
    tempZip.longitude=static_cast<double*>temp2; //use for proper conversion, or other function 
    input.read(temp2,sizeof(double)); 
    tempZip.latitude=static_cast<double*>temp2; 
    zipToCout(tempZip); 
    } 

Несколько замечаний по коду выше,

tempZip = zip; //why this, since you havn't declared any proper assignment 
operator. Use memcpy instead. 

tempZip.postalCode=(atoi)temp; //use for proper conversion, or other function

tempZip.longitude=static_cast<double*>temp2; //use for proper conversion, or other function 

Позвольте мне знать, если это решит вашу проблему.

+0

Немного дайте мне. Я проверю это и вернусь к вам, Большое спасибо за быструю помощь! – user2990286

+0

Это работает так же хорошо, оба предоставленных ответа будут делать трюк, мне нужно было использовать '*' вместо '&' в прототипе, поэтому я использовал первый ответ, но я действительно понимаю, как преобразовать сейчас, что очень помогает. Спасибо огромное! – user2990286

+0

Это только позволяет мне выбрать один, и поскольку я использовал код из первого, я выбрал его. Если есть подобная кнопка, которую я пропускаю, дайте мне знать, потому что я определенно буду, так как ваш ответ тоже был очень полезен. – user2990286

Смежные вопросы