Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
#1

Чтение файла с данными типа real. Тип real в билдере или как его "обойти"? - C++

26.10.2015, 09:28. Просмотров 777. Ответов 41
Метки нет (Все метки)

Читаю файл в структуру,

C++
1
2
3
4
5
6
7
8
9
double Fdat;
 
struct STR
       {
        ...
 
       } rec
 
read( Fdat,(char *)&rec,sizeof(rec));
но данные на выходе получаются, вежливо говоря, не совсем те, которые должны. Описание струкруты самого файла у меня есть. Подозреваю, что проблема в том, что в структуре читаемого файла присутствует тип Real, 6 байт, а в билдере, как я понял, нет этого типа, есть float или double по 4 и 8 байт соответственно. Помимо этого, ещё в файле есть IUNT и UDINT, я их объявляю как unsigned int и unsigned long int, и это верно, если не ошибаюсь.
Читаю другие файлы другой структуры, где нет вещественного типа (и Fdat как int идёт), и всё как надо читается.
Верно ли я понял причину (real) и что можно сделать, какой тип объявить вместо real? Если все же double, то как читать 6 байт? Пробовал сделать так

C++
1
read( Fdat,(char *)&rec,sizeof(rec)-(sizeof(float))/2); // типа отнимаем 2 лишних байта
, но результата положительного это не дало. Помогите, пожалуйста. Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2015, 09:28
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Чтение файла с данными типа real. Тип real в билдере или как его "обойти"? (C++):

При компиляции ошибка: C2228: left of ".real",".imag" must have struct/class/union - C++
Помогите, пожалуйста! Компилирую в VS2010... Ошибка: C2228: left of ".real",".imag" must have struct/class/union... Почему возникает эта...

Given real numbers a, b, c. Find if a quadratic inequality ах2 + bx + с = 0 has real roots. If it does, output them - C++
ВОТ задача помогите решить Given real numbers a, b, c, where a is not 0. Find if a quadratic inequality ах2 + bx + с = 0 has real...

Дано: a:array[1…n] of real;p:real;k:integer;(a[1]<=a[2]<=⋯<=a[n],0<k≤n). - C++
Дано: a:array of real;p:real;k:integer;(a&lt;=a&lt;=⋯&lt;=a,0&lt;k≤n). Удалить из a элемент с номером k (т.е. a) и вставить элемент, равный p, так,...

Error C2679: бинарный "<<": не найден оператор, принимающий правый операнд типа "std::string" (или приемлемое - C++
эмулятор работы банкомата Например #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;time.h&gt; #include...

"Чудеса типа float" или "Куда девалась информация?" - C++
кусок кода: int k=100; float sum=0; for (int i=; i&lt;k; i++) for(int j=1; j&lt;i; j++) sum+=1/(2*j+i) ...

Определить тип данных "Запись", имеющий поля "Фамилия", "Пол", "Зарплата" - C++
определить тип данных запись имеющий поля фамилия пол зарплата. определить массив из 10 записей. в программе ввести в массив данные и...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
26.10.2015, 13:18 #16
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Вот лет 20 назад такими сдвигами и масками и конвертил
Ты разве не студент?
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
26.10.2015, 13:27  [ТС] #17
Цитата Сообщение от nmcf Посмотреть сообщение
Вот функция. Пользуйся
Спасибо большое, буду пробовать. А если в структуре у меня массив real (будущий double), это же не принципиально?

Должно быть что-то вроде этого?
C++
1
2
read( Fdat,(char *)&rec,sizeof(rec));
data.PutElement(convert_real_to_double(rec.Progr[i]), i, j);
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
26.10.2015, 13:48 #18
В структуре у тебя должен быть массив из 6 char в том месте, где real. А после считывания преобразуешь.
Твой пример не понял. Если в rec поле:
C++
1
char real48[6];
то функцию вызывать:
C++
1
convert_real_to_double(rec.real48)
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
26.10.2015, 13:48  [ТС] #19
Ошибку incompatible types выдает, когда делаю так, как выше из своего примера.

rec.Progr[i] объявляю тоже как char в структуре, тогда выдает cannot convert int to char*.

Цитата Сообщение от nmcf Посмотреть сообщение
В структуре у тебя должен быть массив из 6 char в том месте, где real. А после считывания преобразуешь.
Твой пример не понял. Если в rec поле:
Спасибо, буду пробовать. В моем примере я просто считываемое значение вставляю в вариантный массив через PutElement.
Fulcrum_013
664 / 732 / 72
Регистрация: 14.12.2014
Сообщений: 5,701
Завершенные тесты: 3
26.10.2015, 13:52 #20
Цитата Сообщение от nmcf Посмотреть сообщение
Ты разве не студент?
Да уже 15 лет как диплом получил.

Цитата Сообщение от Jaydens_Blues Посмотреть сообщение
Вообще, цель написать одну универсальную программу
В этой универсальной программе придется делать отдельную функцию для чтения каждого из видов форматов. т.к. Real них в разныъ местах как понимаю, и применять функцию конвертирования в Double к каждому полю real.
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
26.10.2015, 13:53 #21
Ты покажи, как у тебя структура объявлена.
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
27.10.2015, 06:27  [ТС] #22
Цитата Сообщение от nmcf Посмотреть сообщение
Ты покажи, как у тебя структура объявлена.
Она объявлена вот так:

C++
1
2
3
4
5
6
7
8
9
10
struct STR {
                  unsigned int    Year;
                  unsigned int    Month;
          unsigned int    Day;
          unsigned int    Hour;
                  unsigned int    Minute;
                  unsigned int    Second;
                  bool A;
                  double data[n];               // то самое real                 
} rec;
И когда считываю, все данные неверные выходят, из всех полей. Как я понимаю, из-за изначально неверного sizeof, потому что объявлен double
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
27.10.2015, 06:55 #23
Вот так надо, если там один real:
C++
1
2
3
4
5
6
7
8
9
10
struct STR {
                  unsigned int    Year;
                  unsigned int    Month;
          unsigned int    Day;
          unsigned int    Hour;
                  unsigned int    Minute;
                  unsigned int    Second;
                  bool A;
                  char real48[6];               // то самое real                 
} rec;
Ну и где-то вне этой структуры хранить полученный после преобразования double.
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
27.10.2015, 08:04  [ТС] #24
Цитата Сообщение от nmcf Посмотреть сообщение
Ну и где-то вне этой структуры хранить полученный после преобразования double.
Меня что-то стали терзать смутные сомнения... По поводу того, а почему вообще во всех полях данные некорректные? Если в объявленной структуре что-то не то, это сказывается вообще на все получаемые данные или же , например, как минимум самое первое считываемое значение Year должно быть корректным при условии верного объявления его типа данных? Потому что самое первое значение Year одно и то же, если только я тип не меняю, например, на char. И значение это неверное
Fulcrum_013
664 / 732 / 72
Регистрация: 14.12.2014
Сообщений: 5,701
Завершенные тесты: 3
27.10.2015, 08:16 #25
Цитата Сообщение от Jaydens_Blues Посмотреть сообщение
И когда считываю, все данные неверные выходят, из всех полей. Как я понимаю, из-за изначально неверного sizeof, потому что объявлен double
ну при таких раскладах однозначно нужен sizeof-2 байт на структуру читать.

Добавлено через 6 минут
Это если выравнивание не учитывть. Поэтому и говорю сделай на Дельфе копию паскалевской структуры и ее чтение из типизированного файла, а уже в Builder-е приделай оператор копирования к этой своей с++ структуре из дельфовской.
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
27.10.2015, 08:20 #26
Ну если размер структуры не верный, то будет сдвиг и поля до real будут верны только у самой первой структуры, если ты их, конечно, правильно объявил. Что там за UINT? Это древний 16-битный int или современный? А выравнивание задаёшь?
Что известно про ту структуру? Какой размер в байтах?
Fulcrum_013, ну при чём тут Delphi? Надо выяснить размеры полей.
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
27.10.2015, 08:26  [ТС] #27
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
ну при таких раскладах однозначно нужен sizeof-2 байт на структуру читать.
В случае, если есть массив, то, наверное, sizeof-(2*N), где N это размер массива? Да в любом случае, хоть сколько отнимаю, самое первое считываемое значение первого поля (Year) остается неизменным. При многократном чтении из цикла, последующие - да, меняются, хотя и там мало чего адекватного. Такое ощущение, что меня немножко...гм... дезинформировали со структурой, что ли.

Добавлено через 5 минут
Цитата Сообщение от nmcf Посмотреть сообщение
Ну если размер структуры не верный, то будет сдвиг и поля до real будут верны только у самой первой структуры, если ты их, конечно, правильно объявил. Что там за UINT? Это древний 16-битный int или современный? А выравнивание задаёшь?
Ну вот, значит надо добиваться правильности данных до Real сперва... Выравнивание, это которое data alignment в настройках билдера? Да, я пробую разные значения, мало что меняется в положительную сторону, по-умолчанию Double Word стоит и файлы немного другого типа открываются хорошо
nmcf
5309 / 4629 / 1550
Регистрация: 14.04.2014
Сообщений: 18,437
27.10.2015, 08:27 #28
Тебе известно какие значения записаны в файл, скажем, для первой структуры? Т. е. что должно быть в полях по-правильному? Дамп сделай и покажи.
Fulcrum_013
664 / 732 / 72
Регистрация: 14.12.2014
Сообщений: 5,701
Завершенные тесты: 3
27.10.2015, 08:56 #29
Цитата Сообщение от nmcf Посмотреть сообщение
ну при чём тут Delphi? Надо выяснить размеры полей.
Компилятор выяснит. Кстати то что ты насчитаешь в памяти с учетом выравнивания может не соответствовать тому что в файле. Причина - выравнивание, и как паскаль его обрабатывает при записи в типизированный файл. При том что есть нативные для билдера средства чтения этих файлов, а не этот байтослесарный лисапед и пляска с бубном для определения сайза для каждого варианта структуры.

Добавлено через 3 минуты
Цитата Сообщение от Jaydens_Blues Посмотреть сообщение
Такое ощущение, что меня немножко...гм... дезинформировали со структурой, что ли.
Паскалевский вариант структуры в студию плиз. И версию паскаля. Но так понимаю паскаль додельфовый. в дельфовом пользовали бы TDateTime для времени а не этот хоровод. И Real был бы 8 байтным double. Прога вообще 32-битная или 16-битная?
Jaydens_Blues
0 / 0 / 0
Регистрация: 15.10.2014
Сообщений: 30
27.10.2015, 09:41  [ТС] #30
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Паскалевский вариант структуры в студию плиз
Значит буду пытать авторов программы, структуру смотреть непосредственно в коде и т.д, т.к. про неё практически не знаю ничего. Другие файлы, с которыми нет проблем, как раз используют и TDateTime, не использует вещественные типы и т.д. и всё там нормально. Но зачем-то они сделали несколько вариаций программы и получается всё через одно место, они сами же разными программами открывают эти же свои файлы... Я вот одну хочу сделать. Ладно, буду экспериментировать и попутно пытать людей)

Добавлено через 1 минуту
Цитата Сообщение от nmcf Посмотреть сообщение
Тебе известно какие значения записаны в файл, скажем, для первой структуры? Т. е. что должно быть в полях по-правильному?
Точно я знаю дату, которая должна быть, вот я и пытаюсь вытянуть хотя бы год 2015, а получается фигня, какой бы я тип вместо UINT не задал
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2015, 09:41
Привет! Вот еще темы с ответами:

Массив шаблонов или как обратиться к элементам разного типа, хранящиеся в одном "списке" по индексу - C++
Собственно, вот такой вот вопрос. Очень нужно решение. Спасибо.

Класс "одномерный массив" и методы для работы с его данными - C++
Описать класс одномерный массив, содержащий его элементы и их количество, а так же методы: вывода всех значений на экран, нахождения...

Error: значение типа "const char" нельзя присвоить сущности типа "double" - C++
#include &lt;iostream&gt; #include &lt;iomanip&gt;// using namespace std; void main(void) { const int k=5; int a=10; unsigned int...

Значение типа "void" нельзя использовать для инициализации сущности типа "int" - C++
Не понимаю, почему компилятор считает, что s.pop() это значение типа &quot;void&quot;.. он же вернет этот удаляемый элемент? Как исправить? void...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
27.10.2015, 09:41
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru