СообЧа > База Знаний > Программирование > Pascal

Вопрос

Юнит CRT криво написан, из-за чего на быстрых машинах выдает Run-time error 200. Так вот, какие строки нужно изменить, чтобы этого не было?

Ответ

Да, действительно, так оно и есть. Есть программка — CrtDebug, которая «ремонтирует» уже откомпиленные проги на паскале — например, если у тебя exe-шник есть, а исходника на паскале нету. Она меняет 2 байта и все становится клево :) Можно эти 2 байта и ручками поменять:
найти последовательности
8B C2 B7 37 F6 F7
и такую:
F7 D0 F7 D2 B9 37 00 F7 F1
и замените в них 37 на FF.

Андрей, Garry

Можно заменить борландовский CRT на работающий, например, на
remax22.chat.ru
ftp.elf.stuba.sk/pub/pc/utilfile
Для обработки exe — еще пример:
members.nbci.com
А еще лучше — перейти на 32bit freepascal.org

Иван

Вопрос

Необходимо использовать в своей программе регулярные выражения. Как?

Ответ

Посмотрите исходники компонента TRegExpr :

http://anso.virtualave.net/regexpr.zip- сам компонент

http://anso.virtualave.net/regexpru.zip- русский хелп

Из конференции Expert_FAQ

Вопрос

Кто-нибудь занимался сопряжением компа с самодельными устройствами? Интересует работа с принтерным портом,программинг на турбо паскале желательно с ассемблерными вставками

Ответ

Вопрос емкий, и всю теорию в письме не выложишь, но примерчиком помочь можно.

Непонятно только. Зачем тебе ассемблерные вставки, если все можно сделать на языке высокого уровня…

Вот несколько процедур из реально работающей программы

Function SPI_PortInit:boolean;
Begin 0 ba:= memw[$40:$08];
0000000000000 { узнаем адрес порта LPT1 } 0 if ba=0 then SPI_PortInit:=false 0 else Begin 000 prttmp:=$0B;
0000000 { для режима записи в LPT0 } 000 port[ba]:=$ff;
000 port[ba+2]:=$0B;
0 End;
End;
Procedure SetBit(maska,value:byte);
Begin 0 if value=0 Then prttmp:=prttmp or maska 0 else prttmp:=prttmp and not maska;
0 port[ba+2]:=prttmp;
End;
Procedure SetBitData(maska,value:byte);
Begin 0 if value=0 Then datatmp:=datatmp or maska 0 else datatmp:=datatmp and not maska;
0 port[ba]:=datatmp;
End;
function status(n:byte):boolean;
0 { выдает состояние n бита статуса пар. порта } var a:byte;
begin 0 a:=port[ba+1];
0 status:=boolean(n and a);
end;


Из конференции Expert_FAQ

Вопрос

Эмулятор банкомата

Заданы количества купюр след. достоинств:
1,3,5,10,20,50,100,500,1000,2000,5000.

Можно ли набрать из этих монет заданную сумму? Если можно, то указать как это сделать. Подскажите, как решить эту задачу?

Ответ

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

Решение:

Пусть надо набрать сумму X рублей. Организуем следующий цикл:

Пока остаток не равен 0
1. Берем номинал купюры (Y), начиная с самой большой.
2. Ищем количество таких купюр, которое не превышает исходной суммы. N = X div Y.
3. Находим остаток, который заведомо меньше Y и который надо будет покрыть. R = X — N*Y
4. Переходим к пункту 1

Пример:

Пусть нужно найти набор купюр для суммы 12345 рублей.
X = 12345

1) Y = 5000, N = 2, R = 12345 — 2*5000 = 2345
2) Y = 2000, N = 1, R = 2345 — 2000 * 1 = 345
3) Y = 1000, N = 0, R = 345 — 1000*0 = 345
4) Y = 500, N = 0, R = 345 — 500*0 = 345
5) Y = 100, N = 3, R = 345 — 3* 100 = 45
6) Y = 50, N = 0, R = 45 — 0*50 = 45
7) Y = 20, N = 2, R = 45 — 2*20 = 5
8) Y = 10, N = 0, R = 5 — 10*0 = 5
9) Y = 5, N = 1, R = 5-1*5=0

Конец цикла.

Имеем: для набора суммы 12345 рублей нужно

5000 — 2
2000 — 1
1000 — 0
500 — 0
100 — 3
50 — 0
20 — 2
10 — 0
5 — 1

До остальных даже не дошло…

Так как можно представить например 50 = 2*20 + 10, то это не единственный алгоритм.

Из конференции Expert_FAQ

Вопрос

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

Ответ

Для каждого узла дерева создаешь динамический список, в котором хранишь адреса дочерних к данному узлов.

Главное — корректно освобождать память и не запутаться какой указатель куда указывает :)

Из конференции Expert_FAQ

TYPE
UK=^DER;
DER=RECORD
INF:INTEGER;
LEFT:UK;
RIGHT:UK;
END;
VAR
ROOT,P,Q:UK;

а потом вводите(читаете) нужное значение и включаете в нужное место :) Если нужен алгоритм формирования дерева.

moorka_ru

Вопрос

Есть строка S=' word1 word2 etc '. Как удалить из строки S боковые пробелы.
Т.е. надо сделать то же самое, что в Delphi делает Trim.

Ответ

Вот когда-то давненько для собственных нужд делал:

Function LTrim(s_target: String):String;
{удаление всех пробелов слева} Begin If Length(S_Target)<1 then {если строка пустая} begin LTrim:=S_Target;
Exit;
end;
While S_Target[1]=' ' do Delete(S_Target,1,1);
{удаляем по одному пробелы слева} LTrim:=S_Target;
End;
{LTrim}
{-----------------}
Function RTrim(s_target: String):String;
{удаление всех пробелов справа} Begin If Length(S_Target)<1 then begin RTrim:=S_Target;
Exit;
end;
While S_Target[Length(S_Target)]=' ' do Delete(S_Target,Length(S_Target),1);
RTrim:=S_Target;
End;
{RTrim}
{-----------------}
Function AllTrim(s_target: String):String;
{удаление всех пробелов слева и справа используя две предыдущие функции} Begin If Length(S_Target)<1 then begin AllTrim:=S_Target;
Exit;
end;
S_Target:=LTrim(S_Target);
S_Target:=RTrim(S_Target);
AllTrim:=S_Target;
End;
{AllTrim}


Вызов к примеру такой: rezult:=AllTrim(' строка-цель ');

Из конференции Expert_FAQ

Вопрос

Требуется алгоритм нахождения машинного нуля/бесконечности/эпсилон для Single, Double и Extended.

Ответ

#include <stdio.h>
void main()
{
float e,e1;
int k=0;
e=1.0;
m: e=e/2.0;
e1=e+1.0;
k++;
if (e1>1.0) goto m;
printf("\n Число делений на 2 %6d\n",k);
printf("машинный нуль %e\n",e);
};


© Подбельский В.В., Фомин С.С., Сайт «Системного Программирования»

Вопрос

Не работает модуль Graph. В опциях>>директории стоит адрес Units. В теле программы пишу

program sed;
uses graph;
var
d,m:integer;
begin
initgraph(d,m,'D:\tp\bgi');
d:=detect;
readln;
bar(0,0,5,5);
closegraph;
readln;
end.

Выдает типа «Графический режим не инициализирован». Из-за чего это?

Ответ

Во-первых, необходимо определиться с видом графического адаптера и графическим режимом . Как раз именно это и делает система автоматически в момент присвоения переменной d (d:=detect). Поэтому это присвоение должно стоять перед вызовом процедуры InitGraph.

Во-вторых, нужно убедиться, что правильно указан путь к BGI-драйверам в параметрах процедуры инициализации InitGraph.

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

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

procedure GrInit;
VAR graphDriver : integer;
GraphMode : integer;
ErrorCode : integer;
BEGIN GraphDriver:=Detect;
InitGraph(GraphDriver,GraphMode,'');
ErrorCode:=GraphResult; if ErrorCode <>
grOk then begin writeln('Ошибка графики: ',GraphErrorMsg(ErrorCode));
writeln('Программа остановлена. ');
halt(1);
end;
END;


Описав эту процедуру (можно ее доработать на предмет пути к BGI-драйверам), можно к ней обращаться когда нужно инициализировать графический режим. Тогда ваш код будет выглядеть приблизительно так:

program sed;
uses graph;
procedure GrInit;
VAR graphDriver : integer; GraphMode : integer;
ErrorCode : integer;
BEGIN GraphDriver:=Detect;
InitGraph(GraphDriver,GraphMode,'D:\tp\bgi');
ErrorCode:=GraphResult;
if ErrorCode <> grOk then begin writeln('Ошибка графики: ',GraphErrorMsg(ErrorCode));
writeln('Программа остановлена. ');
halt(1);
end;
END;
BEGIN GrInit;
{Попытка инициализировать графический режим} SetColor(14);
{цвет пера — желтый} SetBkColor(1);
{цвет фона — синий} For Radius:=1 To 5 Do Circle(100, 100, Radius * 10);
{рисуем круги} closegraph;
readln;
end.


Существует возможность внедрить определенный BGI-драйвер в ЕХЕ-файл, тогда не нужно будет «таскать с программой» файл BGI (впрочем, как и необходимые шрифты).

Из конференции Expert_FAQ



Copyright © 2000-2004 Сообщество Чайников
Контактная информация