Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 10.11.2022
Сообщений: 23
RAD XE3+

Проблемы при чтении из файла в запись

11.11.2022, 14:43. Показов 1846. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
День добрый.
Стоит задача в Delphi прочесть часть структурированного файла в запись. В последующем изменить и записать обратно.
Имеется описание формата для С.
Описал формат заголовка записью, заменив типы С на аналоги Delphi.
Написал процедуру чтения...
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
procedure TForm1.ButtSelXTFClick(Sender: TObject);//Выбрать XTF
var
st: String;
HDR1: XTFFILEHEADER;
t: array [0..1023]of BYTE;
str: string;
 
begin
  if Form1.OpenDialog1.Execute then begin
     Form1.Edit1.Text := Form1.OpenDialog1.FileName;
     XTFstream:=TFileStream.create(Form1.Edit1.Text, fmOpenReadWrite);
     with XTFstream do
     try
        Seek(0, soFromBeginning);
        read(HDR1, 1024);
        Seek(0, soFromBeginning);
        read(t, 1024);
        st:=HDR1.RecordingProgramVersion;
     except
        ShowMessage('Неизвестная ошибка');
     end;
     XTFstream.Free;
  end;
end;
и столкнулся с непонятностями.
При выполнении программы

в поле string[8] закидывается не 8 а 83 символа, причем начиная со смещения 03, а не 02. Что удивительно, остальные поля начали заполнятся не с 86 смещения, а с 11го, но "сдвинулись" на этот байт. Далее почему-то поле SonarType тоже при заполнении сдвинулось на байт.

Посмотрев на эту чехарду, заменил все поля String, на массивы AnsiChar - они заполняются без сдвигов

и массив скинуть в строковую переменную не проблема, только как бы из нее поудалять "нолики", чтоб при обработке не получалось показанных нюансов.

Дальше всё виделось уже в розовом свете пока не дошел до ReferencePointHeight.
Вроде бы всё просто:
4хбайтный float заменен таким же single;
В файле по указанному смещению четыре нуля;
Указатель после чтения Reserved2 должен быть на 178 позиции...

но судя по ненулевому содержанию ReferencePointHeight и обрезанному ProjectionType, то ли читает больше, то ли как и со String-ом - смещается.

Помогите пожалуйста разобраться почему так происходит? Может присоветуете как можно сделать проще, лучше, да еще чтоб работало .
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.11.2022, 14:43
Ответы с готовыми решениями:

Проблемы с кириллицей при чтении из ini-файла
есть класс для работы с INI-фйлом public class cIni{ private static extern int WritePrivateProfileString(string pSection, string...

Проблемы при чтении односвязного списка из файла
В общем, есть у меня структура односвязного списка со всеми элементарными функциями для неё, и пришёл черёд как-нибудь записать этот список...

"Нарушение прав доступа при чтении по адресу" при чтении структур из бинарного файла
Пытаюсь разобраться со структурами в бинарных файлах. Допустим, есть массив структур. Записываю его в бинарный файл (закомментированный...

37
 Аватар для Newby52
43 / 38 / 5
Регистрация: 24.07.2018
Сообщений: 214
Записей в блоге: 6
14.11.2022, 12:09
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от D1973 Посмотреть сообщение
а обработка строки прекращается.
И опять не совсем так. Чем прекращается? Если записать такую строку, например, в файл, то она запишется вся полностью.
Delphi
1
2
3
4
5
6
7
8
9
procedure TForm6.BitBtn1Click(Sender: TObject);
var s:string;f:textfile;
begin
s:='1234567890';
s[4]:=#0;
AssignFile(f,'c:\1.txt');Rewrite(f);
Writeln(f,s);
CloseFile(f);
end;
Миниатюры
Проблемы при чтении из файла в запись  
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
14.11.2022, 12:11
Цитата Сообщение от Aesh Посмотреть сообщение
Но в файле текстовое поле содержит 'Port780'#0'y : read' и именно вот тот "нолик" посередине строки я назвал дичью.
Поле может содержать строку из 16 (?) символов максимум. Но может содержать и из 1-15 символов. В этом случае, конец строки обозначается как раз, нулём (#0). То есть, Port780 это верное значение поля. Остальные символы можно не учитывать.
0
Модератор
 Аватар для D1973
9954 / 6490 / 2461
Регистрация: 21.01.2014
Сообщений: 27,495
Записей в блоге: 3
14.11.2022, 14:47
Цитата Сообщение от Newby52 Посмотреть сообщение
то она запишется вся полностью
Вы остановились на пол-пути. Теперь, после Вашего, вот этот кодик... Что покажет? Именно это я и имел в виду.
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure TForm1.Button2Click(Sender: TObject);
var
  s: String;
  f: TextFile;
begin
  AssignFile(f, 'c:\1.txt');
  reset(f);
  read(f, s);
  CloseFile(f);
  ShowMessage(s);
end;
0
 Аватар для Newby52
43 / 38 / 5
Регистрация: 24.07.2018
Сообщений: 214
Записей в блоге: 6
14.11.2022, 15:17
Цитата Сообщение от D1973 Посмотреть сообщение
Что покажет? Именно это я и имел в виду.
Он покажет, что строка благополучно считалась в том виде, в котором и была записана. А потом ShowMessage благополучно преобразовала её в Pchar, для которого, как раз #0 и является концом строки.
Миниатюры
Проблемы при чтении из файла в запись  
0
Модератор
 Аватар для D1973
9954 / 6490 / 2461
Регистрация: 21.01.2014
Сообщений: 27,495
Записей в блоге: 3
14.11.2022, 15:47
Цитата Сообщение от Newby52 Посмотреть сообщение
преобразовала её в Pchar, для которого, как раз #0 и является концом строки.
А куда Вы от этого денетесь? Цитируя сайт CyberGuru:
Потеря куска строки после символа #0 происходит всегда, когда есть преобразование ShortString или AnsiString в PChar, даже неявное. Например, все API-функции работают с нуль-терминированными строками, а визуальные компоненты - просто обёртки над этими функциями, поэтому вывести с их помощью на экран строку, содержащую #0, целиком невозможно.
0
 Аватар для Beltar
1078 / 517 / 42
Регистрация: 05.05.2022
Сообщений: 3,678
14.11.2022, 16:04
Вы сейчас про какие "нолики"? По моему Вы путаете символ '0' и символ с кодом #0. Если в строке символов встречается символ с кодом #0
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
      itpStr:
        begin
        Buf.VStr:='';
        //Buf.VStr:=Item.ValueStr;
        {Да, <мат> по преобразованиям варианта в строку, но #0 <мат>}
        for i:=Low(Item.ValueStr) to High(Item.ValueStr) do
          begin
          if Item.ValueStr[i]<>#0 then Buf.VStr:=Buf.VStr+Item.ValueStr[i]
                                  else Break;
          end;
        for i:=Low(Buf.VStr) to High(Buf.VStr) do
          begin
          if Buf.VStr[i]=#0 then
            begin
            Buf.VStr[i]:=' ';
            DM.AddMsgToLog('Был 0 в строке: '+Buf.VStr);
            end;
          end;
        end;
Этот УЖАС из реального проекта, такую вот фигню с #0 в центре я получал с OPC-сервера. Как?? Я не знаю, я сам офигел, т. к. там сервер явно на C++ нарисован, но шло то, что шло, пришлось с этим бороться. Визуально строка по #0 резалась, но если посмотреть в отладчике, то она отображается полностью, хоте Length тоже возвращает число символов только до #0. ЕМНИП изначально была только вторая проверка, а потом добавилось уже тупо копирование по символу с проверкой на #0, а вторая проверка осталась незакомментированной. Ну а потом обычное, фиг с ним, работает, не трогай. Pos с #0 ЕМНИП просто не работает.

Как известно, в Delphi длина строки определяется в описывающей ее "структуре", где ссылка на данные, счетчик ссылок и остальная фигня, кодировка в юникодовых версиях, то от чего юзера в 99.99% случаев избавляет компилятор, и заканчивается для удобства совместимости с Си-строками на #0, но я не помню, чтобы где-то говорилось, что #0 не может быть в середине строки. И я не удивлюсь, если в самой VCL по этому поводу у разных процедурок могут быть разные мнения.
0
Модератор
 Аватар для D1973
9954 / 6490 / 2461
Регистрация: 21.01.2014
Сообщений: 27,495
Записей в блоге: 3
14.11.2022, 16:17
Цитата Сообщение от Beltar Посмотреть сообщение
такую вот фигню с #0 в центре я получал с OPC-сервера
беда-печаль... Мои соболезнования.
Цитата Сообщение от Beltar Посмотреть сообщение
у разных процедурок могут быть разные мнения
что есть, то есть...
0
 Аватар для Newby52
43 / 38 / 5
Регистрация: 24.07.2018
Сообщений: 214
Записей в блоге: 6
14.11.2022, 16:26
Давайте в сторону не будем уходить. Началось с этого:
В середине дельфовой строки нолики вполне видны.
Цитата Сообщение от D1973 Посмотреть сообщение
Если в строке символов встречается символ с кодом #0 ... - компилятор сразу понимает, что текст закончился и то, что осталось после этого символа - ему до фонаря
Речь шла о дельфовой строке - это string.
В string вполне могут быть в середине и #0, которым
текст не заканчивается
и
то, что осталось после этого символа
- ему не до фонаря, а он честно воспринимает это, как продолжение строки, и это продолжение участвует во всех дельфийских операциях со строкой, например, при конкатенации и т.д. А то, что при вызове API-шных функций, дельфийская строка преобразуется в PChar - естественно, но это уже не дельфийская строка.
0
14.11.2022, 16:32

Не по теме:

Цитата Сообщение от Newby52 Посмотреть сообщение
Давайте в сторону не будем уходить.
Знаете, я что-то и так уже отступил от своего принципа - не спорить. Хотите считать, что #0 допустим в середине String-строки - да на здоровье. Просто будьте готовы к неадекватным результатам в самый неожиданный момент. А я считаю, что там его быть не должно и от этой печки, как говорится, танцую... Никому не хочу своего мнения навязывать, поступайте как знаете.

0
 Аватар для Newby52
43 / 38 / 5
Регистрация: 24.07.2018
Сообщений: 214
Записей в блоге: 6
14.11.2022, 16:50
Цитата Сообщение от D1973 Посмотреть сообщение
А куда Вы от этого денетесь?
Куда угодно. Если мне вдруг приспичит зачем-то выводить такие строки, есть не API-шные возможности, например, Canvas.TextOut

Добавлено через 1 минуту
Цитата Сообщение от D1973 Посмотреть сообщение
А я считаю, что там его быть не должно
А это не всегда зависит от нас.

Добавлено через 2 минуты
Цитата Сообщение от D1973 Посмотреть сообщение
Хотите считать, что #0 допустим в середине String-строки - да на здоровье.
Есть разница - "технически допустим", о чём я и говорил, или "так следует делать" - о чём я не говорил.
0
 Аватар для Beltar
1078 / 517 / 42
Регистрация: 05.05.2022
Сообщений: 3,678
14.11.2022, 19:20
А то, что при вызове API-шных функций
Блин, вот я тупой, VCL ведь стандартные контролы, вроде TEdit и TListView не сама рисует, они все виндовые, разумеется, если в них такую строку сунуть, то она где-то обсишится и будет визуально обрезана.

есть не API-шные возможности, например, Canvas.TextOut
А разве это не прослойка к виндовому DC?
0
 Аватар для Newby52
43 / 38 / 5
Регистрация: 24.07.2018
Сообщений: 214
Записей в блоге: 6
14.11.2022, 19:47
Цитата Сообщение от Beltar Посмотреть сообщение
А разве это не прослойка к виндовому DC?
Да, но со string работает корректно. Там просто указывается буфер и длина, а #0, не #0 - ей плевать.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
15.11.2022, 09:44
Всё же, не стоит забывать, что эта строка пришла из файла, в который была записана программой, написанной, скорее всего, на C, и технически не обязана занимать все отведённые байты в структуре, так что, я по прежнему за нуль-терминированную строку.

Aesh, дайте описание структуры CHANINFO, тогда будет понятнее, а то у нас пока на уровне догадок.
0
 Аватар для Newby52
43 / 38 / 5
Регистрация: 24.07.2018
Сообщений: 214
Записей в блоге: 6
15.11.2022, 10:06
Цитата Сообщение от AzAtom Посмотреть сообщение
эта строка пришла из файла, в который была записана программой, написанной, скорее всего, на C, и технически не обязана занимать все отведённые байты в структуре, так что, я по прежнему за нуль-терминированную строку.
Так, с этим никто и не спорит, на 99,(9)% это так.
0
0 / 0 / 0
Регистрация: 10.11.2022
Сообщений: 23
15.11.2022, 16:28  [ТС]
Доброго дня.
Цитата Сообщение от AzAtom Посмотреть сообщение
Aesh, дайте описание структуры CHANINFO, тогда будет понятнее, а то у нас пока на уровне догадок.
Поле содержит 16 символов, а так как файл с данными писался с нуля, то если бы "хвост" от 'Port780'#0'y : read' был бы программе не нужен, то он бы и не писался(ноликами бы дополнили). Но это в любом случае теоретические предположения.

Практически я проблему решил заменяя #0 на другой символ. А в StringGrid данные вообще не обрезаются.
Так что еще раз спасибо за советы.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
15.11.2022, 16:44
Цитата Сообщение от Aesh Посмотреть сообщение
если бы "хвост" от 'Port780'#0'y : read' был бы программе не нужен, то он бы и не писался(ноликами бы дополнили)
Не обязательно. Взяли память размером в 16 байт, она может содержать какие угодно данные. Записали в неё 8 байт, а остальные не трогали. Затем, записали на диск весь буфер 16 байт.
Цитата Сообщение от Aesh Посмотреть сообщение
Практически я проблему решил заменяя #0 на другой символ.
А программа, которая писала этот файл, при открытии файл что выдаёт в имени канала?

Ещё возникает вопрос. Имя должно состоять из читаемых символов, иначе, с чего бы его называть "именем"? Какой символ программа должна нарисовать при встрече кода #0?
0
0 / 0 / 0
Регистрация: 10.11.2022
Сообщений: 23
15.11.2022, 19:29  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
Ещё возникает вопрос. Имя должно состоять из читаемых символов, иначе, с чего бы его называть "именем"? Какой символ программа должна нарисовать при встрече кода #0?
Программа выдает как в Сишном варианте, но ежели помните я выдвигал версию, что просто она так какую то служебную инфу для себя так прячет. Как раньше в "остатке" сектора прятали инфу для защиты от копирования.
Еще в самом начале говорил, что не знаю зачем это все и как должно работать. Разработчики - американцы, у них не очень-то и поспрашиваешь. По работе программы ощущение такое, что писали разные люди, в разное время и без менеджера проекта .
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 21
16.11.2022, 10:46
нет там никаких теорий заговора
как и сказано выше, программа просто выплевывает буфер фиксированной длины. из буфера на клиенте читается строка, терминированная нулём.
и нет никаких скрытых символов просто потому, что длина текста может меняться, тогда придется предположить, что количество "скрытого" меняется тоже. И как его тогда дешифровать?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.11.2022, 10:46

При чтении данных из 1 файла и запись этих данных во 2 файл дублируются последние строки
Когда считываю данные из одного файла и переношу эти же данные в другой файл, у меня дублируются строки ifstream...

Проблемы при чтении диска
Есть такая проблема, Всовую диск в дисковод, а он его даже не ощущяет. Что это такое и как с этим бороться?

Проблемы c кодировкой при чтении исходника HTML через webBrowser
Нужно вывести исходный код HTML страницы в richTextBox'е. Для этого создан объект типа webBrowser. Исходный код беру через...

Ошибка при чтении данных, запись в list
Добрый день, проблема в следующем, вот код: int *spectrA=new int; int *spectrB=new int; double *X= new double; ...

Как проверояется, достигнут ли конец файла при чтении из текстового файла?
Как проверояется, достигнут ли конец файла при чтении из текстового файла? Каким образом функция возвращает результат своей работы...


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

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru