Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
 Аватар для AHBAR
1077 / 488 / 316
Регистрация: 05.04.2013
Сообщений: 2,141
RAD XE3+

Консольное приложение зависает при использовании String и TStringList

09.06.2020, 22:27. Показов 1209. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вопрос есть.
uses Classes можно использовать в консольном приложении?
пишу консольное приложения для обработки (типа конвертера) бинарных файлов в текстовый
Для удобства создал класс
Delphi
1
2
3
4
5
6
7
8
9
10
{$APPTYPE CONSOLE}
 
{$R *.res}
 
uses
  System.SysUtils, System.Types, System.Classes, IOUtils;
 
type
  TMyClas = class 
....
Весь код очень большой, приводить смысла нет. проблема в том, что на Delphi 10.3 приложение зависает.
Но не зависает, если закомментировать такие строки как:
Delphi
1
2
3
4
5
//s : String;
//rec84 : array of byte;
s := s + IntToHex(rec84[i], 2);
s := dat + ';' + tim + ';' + s1 + ';' + s1 + ';' + dur.ToString; //все String,  dur - Integer
l.Add(s); //L : TstringList
Код компилируется нормально, но при обработки файла приложение зависает

Хотел узнать, может я библиотеки некорректно подключаю в uses? (да ну бред!)
Или в delphi10 какие-то несовместимости String и/или TstringList? Знаю, что там String=WideString, но не из-за этого же приложуха лажает?

дело в том, что портировал код в Delphi 7 - там прекрасно отрабатывает. Но хочется работать с 10-ой

Вспомнил, переписывал код на приложение в формой - такие же глюки
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.06.2020, 22:27
Ответы с готовыми решениями:

Зависает приложение при использовании Timer
использую обычный таймер для вывода изображения в Image //main aTimer = new System.Timers.Timer(30); aTimer.Elapsed +=...

Как добавить string в ресурсы? (консольное приложение)
Нужно чтобы вводимые во время выполнения программы данные сохранялись в программе, а не в текстовом файлике рядом или типа того. Чтобы в...

консольное приложение (при запуске приложение открывалось на весь экран)
Как сделать, чтобы при запуске приложение открывалось на весь экран?

23
 Аватар для Пытливый
3763 / 2267 / 705
Регистрация: 29.05.2013
Сообщений: 9,622
09.06.2020, 23:32
Цитата Сообщение от AHBAR Посмотреть сообщение
Но не зависает, если закомментировать такие строки как:
а как же оно у вас тогда компилится, если переменные не объявлены? Может у вас там дублирование глобальных и локальных имен переменных?
0
Нарушитель
10225 / 5655 / 1257
Регистрация: 12.03.2015
Сообщений: 26,180
10.06.2020, 00:14
Отладчик найдёт причину мгновенно.
0
451 / 175 / 31
Регистрация: 04.08.2018
Сообщений: 704
10.06.2020, 00:19
Цитата Сообщение от AHBAR Посмотреть сообщение
Весь код очень большой, приводить смысла нет.
Сделайте копию проекта, в копии удалите всё, что не вызывает зависание. Что останется - сюда.
0
Модератор
 Аватар для D1973
9902 / 6440 / 2454
Регистрация: 21.01.2014
Сообщений: 27,337
Записей в блоге: 3
10.06.2020, 05:52
Цитата Сообщение от AHBAR Посмотреть сообщение
s := s + IntToHex(rec84[i], 2);
s := dat + ';' + tim + ';' + s1 + ';' + s1 + ';' + dur.ToString;
Что-то я сути не пойму: Вы дописали к значению переменной s Хекс-значение очередного элемента массива. И тут же заменили значение этой переменной другими данными... Зачем было что-то дописывать, если тут же результат заменить?
И вот эту красоту с плюсами я бы записал как-то так:
Delphi
1
s := Format('%s;%s;%s;%s;%d', [dat, tim, s1, s1, dur]);
0
 Аватар для AHBAR
1077 / 488 / 316
Регистрация: 05.04.2013
Сообщений: 2,141
12.06.2020, 18:53  [ТС]
Цитата Сообщение от Rayvenor Посмотреть сообщение
Сделайте копию проекта, в копии удалите всё, что не вызывает зависание. Что останется - сюда.
В общем, я быстренько начал писать приложение в упрощенном виде. заметил, что могло послужить причиной глюков:
Delphi
1
2
3
4
SetLength(rec84, buffer); //определить память для массива с записью
ms.Position := position;
//считаем пакет в буферный массив для его обработки и вытаскивания данных
ms.Read(rec84[0], SizeOf(AnsiChar) * Length(rec84));
у меня там до этого было:
Delphi
1
ms.Read(rec84[0], SizeOf(Char) * Length(rec84));
Буду дальше писать, посмотрю будут ли зависания. скорее всего должно уйти
Цитата Сообщение от D1973 Посмотреть сообщение
Что-то я сути не пойму: Вы дописали к значению переменной s Хекс-значение очередного элемента массива. И тут же заменили значение этой переменной другими данными
Да это просто код вырванный из контекста для примера.
0
Модератор
4114 / 2346 / 807
Регистрация: 15.11.2015
Сообщений: 9,328
13.06.2020, 07:08
Цитата Сообщение от AHBAR Посмотреть сообщение
ms.Read(rec84[0], SizeOf(AnsiChar) * Length(rec84));
А этот rec84 как определён?

Цитата Сообщение от AHBAR Посмотреть сообщение
у меня там до этого было:
ms.Read(rec84[0], SizeOf(Char) * Length(rec84));
Ну тут понятно, в Delphi 10 Char уже занимает 2 байт, и если в записи AnsiChar, который занимает 1 байт, то будет перезаписана память других переменных и ошибки работы программы обеспечены.
0
 Аватар для AHBAR
1077 / 488 / 316
Регистрация: 05.04.2013
Сообщений: 2,141
13.06.2020, 10:25  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
А этот rec84 как определён?
Delphi
1
rec84: array of byte;
0
 Аватар для Пытливый
3763 / 2267 / 705
Регистрация: 29.05.2013
Сообщений: 9,622
13.06.2020, 11:22
Так вы же читаете в два раза больше данных, чем размер структуры. В XE тип Char это 2 байта, а не 1.
ПС: Хотя неправ, вы переделали на AnsiChar.
Опубликуйте последний проблемный кусок кода, а то уже непонятно как это выглядит сейчас.
0
 Аватар для krapotkin
6847 / 4674 / 1463
Регистрация: 14.04.2014
Сообщений: 20,653
Записей в блоге: 21
13.06.2020, 12:01
если rec84 это array of byte
то
1. есть TBytes, зачем вам еще один тип?
2. sizeOf(rec84) === 4 это размер указателя на массив, а не размер массива
размер массива length(rec84)
3. чтобы подсказать что-то более осмысленное, лучше знать исходную задачу
потому что нет никакой разницы между "бинарными" и "текстовыми" файлами
достаточно просто использовать другие классы для работы с файлом...
0
Модератор
4114 / 2346 / 807
Регистрация: 15.11.2015
Сообщений: 9,328
13.06.2020, 17:23
Цитата Сообщение от AHBAR Посмотреть сообщение
rec84: array of byte;
Тогда, почему не
Delphi
1
ms.Read(rec84[0], SizeOf(byte) * Length(rec84));
?
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
13.06.2020, 17:28
Цитата Сообщение от AzAtom Посмотреть сообщение
SizeOf(byte)
А что тут возможны варианты?
0
Модератор
4114 / 2346 / 807
Регистрация: 15.11.2015
Сообщений: 9,328
13.06.2020, 17:56
northener, так у ТС там SizeOf(Char), который зависит от версии delphi.
0
 Аватар для AHBAR
1077 / 488 / 316
Регистрация: 05.04.2013
Сообщений: 2,141
13.06.2020, 18:48  [ТС]
Цитата Сообщение от Пытливый Посмотреть сообщение
Опубликуйте последний проблемный кусок кода, а то уже непонятно как это выглядит сейчас.
Сейчас уже пока проблем нет, она исчезла после более правильного считывания из TmemoryStream в массив..
Цитата Сообщение от krapotkin Посмотреть сообщение
есть TBytes, зачем вам еще один тип?
не совсем понял. предлагаете писать var rec84: Tbytes вместо var rec84: array of byte ?
Цитата Сообщение от krapotkin Посмотреть сообщение
лучше знать исходную задачу
насчет исходной задачи.. есть файл. в файле есть последовательности из байтов (записи). эти записи начинаются с байта 132=$84, а следующий после него байт - определяет размер записи. теоретически все такие записи должны следовать друг за другом непрерывно, но возможно между записями будут лишние байты (промежутки). Далее из этих записей нужно извлекать определенные данные: некоторые в ХЭКСовом представлении, некоторые в числовом, некоторые как набор символов по таблице ASCII Chr(). Получается своего рода конвертер.

Чтобы реализовать такую задачу, я:
1. гружу файл в TMemoryStream
2. прохожусь циклом по нему, ищу байт=132. как только нашел - оправляю запись в массив байтов.
3. обрабатываю массив, вытаскиваю данные
4. перевожу курсор (ms.Position) на конец записи и снова ищу байт=132 и так до последнего байта ms

======================================== ================
Delphi
1
ms.Read(rec84[0], SizeOf(byte) * Length(rec84));
Если SizeOf(byte) = SizeOf(AnsiChar) = 1 байту, тогда почему нельзя записать?)
Delphi
1
ms.Read(rec84[0], Length(rec84));
Еще мне нужно вытащить из такого массива число, которое состоит из трех последовательных байтов (rec84[i+8], rec84[i+9], rec84[i+10]) но как бы задом наперед, как более правильно это сделать?
Я делаю так:
Delphi
1
du_int := StrToInt('$' + IntToHex(rec84[i+10], 2) + IntToHex(rec84[i+9], 2) + IntToHex(rec84[i+8], 2));
Добавлено через 2 минуты
Цитата Сообщение от AHBAR Посмотреть сообщение
Чтобы реализовать такую задачу, я:
1. гружу файл в TMemoryStream
2. прохожусь циклом по нему, ищу байт=132. как только нашел - оправляю запись в массив байтов.
3. обрабатываю массив, вытаскиваю данные
4. перевожу курсор (ms.Position) на конец записи и снова ищу байт=132 и так до последнего байта ms
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
25
26
27
procedure TForm1.Open1Click(Sender: TObject);
var
ms : TMemoryStream;
i,j:Integer;
position: Int64;
mas : array of byte;
first_byte, sec_byte : byte;
begin
if not OpenDialog1.Execute then exit;
ms := TMemoryStream.Create;
ms.LoadFromFile(OpenDialog1.FileName);
position := 0;
while Position <= ms.Size do BEGIN
      ms.Position := position;
      ms.Read(first_byte, SizeOf(first_byte));
      if first_byte = 132 then Begin
         ms.Read(sec_byte, SizeOf(sec_byte));
         mas := nil;
         SetLength(mas, sec_byte);
         ms.Position := position;
         ms.Read(mas[0], SizeOf(AnsiChar) * Length(mas));
         //Тут идет обработка массива rec84
         inc(Position, sec_byte);
         End else inc(Position);
      END;
ms.Free;
end;
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
13.06.2020, 18:59
Цитата Сообщение от AHBAR Посмотреть сообщение
как бы задом наперед
Нормальный порядок. Непонятно только что это за трехбайтовое целое?

Добавлено через 7 минут
Цитата Сообщение от AHBAR Посмотреть сообщение
как бы задом наперед, как более правильно это сделать?
Delphi
1
2
3
4
var  N3b : Integer;
...
  N3b:=0;
  Move([rec84[i+8],N3b,3);
1
13.06.2020, 19:02

Не по теме:

Нормальный порядок
Для intel нормальный. А для людей - нет. :)

0
 Аватар для krapotkin
6847 / 4674 / 1463
Регистрация: 14.04.2014
Сообщений: 20,653
Записей в блоге: 21
13.06.2020, 19:07
Цитата Сообщение от AHBAR Посмотреть сообщение
предлагаете писать var rec84: Tbytes
просто половина стримовых методов для ввода вывода работает именно с TBYtes

Цитата Сообщение от AHBAR Посмотреть сообщение
Чтобы реализовать такую задачу, я:
1. гружу файл в TMemoryStream
2. прохожусь циклом по нему, ищу байт=132. как только нашел - оправляю запись в массив байтов.
3. обрабатываю массив, вытаскиваю данные
4. перевожу курсор (ms.Position) на конец записи и снова ищу байт=132 и так до последнего байта ms
альтернативный сценарий
1. открываем FS:TFileStream (лучше TBufferedFileStream)
repeat
2. считываем по 1 байту пока не наткнулись на $84
3. когда наткнулись, считываем еще один байт - длину L
4. массиву A:TBytes задаем длину L и считываем L байтов в A. После этого разбираем массив
until FS.Position>=FS.Size;

Добавлено через 2 минуты
т.е. почти то же самое только без этих странностей с SizeOf, Position и всего такого

я исхожу из того, что длину мы получаем в байтах, потому что иначе неясно, почему массив в байтах а не в Char
а если у вас текстовый файл, тогда вряд ли мы кодировали через $84+Len
1
 Аватар для Пытливый
3763 / 2267 / 705
Регистрация: 29.05.2013
Сообщений: 9,622
13.06.2020, 19:15
У него там уже AnsiChar, а это 1 байт. Я потому и просил опубликовать последний вариант кода.
0
 Аватар для krapotkin
6847 / 4674 / 1463
Регистрация: 14.04.2014
Сообщений: 20,653
Записей в блоге: 21
13.06.2020, 19:39
тогда почему все еще array of byte если это TArray<AnsiChar> ?

и если там чисто текст, то что его разбирать?, если можно просто TEncoding.Ansi.Getstring(TBytes) ?
0
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,608
13.06.2020, 19:43
Да байты у него.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.06.2020, 19:43
Помогаю со студенческими работами здесь

Как убрать консольное окно при использовании функции System?
Добрый день, уважаемые пользователи форума! В C++ есть функция System, которая передает команду командной строке, при этом на экране...

Зависает консоль при использовании for
почему зависает консоль ? class Program { static int ar = new { 6, 28, 496, 8128 }; static string result; ...

Как открыть консольное приложение в .NET через другое консольное приложение .NET
Есть один вопрос. Как открыть консольное приложение .NET через другое консольное приложение .NET, чтобы при этом второе приложение...

Зависает программа при использовании цикла while
При открытии второй формы добавил цикл который будет принимать данные от сокет сервера, но когда открывается вторая форма - программа...

Зависает программа при использовании Sleep
Зависает программа,звук играет,картинки не прогружаются P.S в конструкторе все нормально using System; using...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru