goto - с любимыми не расставайтесь, или break не тащит

Любые обсуждения, не нарушающие правил форума.

Модератор: Модераторы

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 06.12.2020 17:04:30

runewalsh писал(а):Хоспаде, да какая у тебя там сложная логика?


Да уж сложнее чем у тебя.

runewalsh писал(а): На goto пишут те, кто ничего другого не знает, и получается чушь.

Код: Выделить всё
FUNCTION CITALNIK(IMJA_FAILA_SOHRANKI5: ANSISTRING;VAR S5: ARRAY OF STRING; VAR Z5: ARRAY OF ANSISTRING;LIMIT: LONGINT): BOOLEAN;
VAR
DLINA_A2: LONGINT=1000;
QQ3,ADRESA3: ARRAY OF BYTE;
ADRESA2: ARRAY OF LONGINT;
M2,E2,C2,I2,R2,Y2,T2: LONGINT;
KOLP: LONGINT;
X64: INT64;
{$IFNDEF LINUX}
Z64: SYSUTILS.THANDLE;
{$ENDIF}
{$IFDEF LINUX}
Z64: INT64;
{$ENDIF LINUX}
LABEL
1,2,5,  99,100,101;
BEGIN
CITALNIK:=FALSE;
{$IFDEF WINDOWS}
IMJA_FAILA_SOHRANKI5:=PUTI_MAZDAJA(IMJA_FAILA_SOHRANKI5);
{$ENDIF WINDOWS}
IF PADLOFAIL(IMJA_FAILA_SOHRANKI5)=FALSE THEN GOTO 101;
KOLP:=LENGTH(S5);
Z64:=SYSUTILS.FILEOPEN(IMJA_FAILA_SOHRANKI5, fmOpenRead);
IF Z64=VINDOFAILOBAG THEN GOTO 100; //КОНСТАНТА ЕСТЬ ДЛЯ ЛИНУКСА, ВИН32 И ВИН64
X64:=SYSUTILS.FILESEEK(Z64,0,2);
SYSUTILS.FILESEEK(Z64,0,0);
IF X64>LIMIT THEN X64:=LIMIT;
IF X64<1 THEN GOTO 99;
SETLENGTH(QQ3,X64+200);
FOR M2:=X64 TO X64+200-1 DO QQ3[M2]:=0;
M2:=X64;
E2:=0;
SYSUTILS.FILEREAD(Z64,QQ3[1],X64);
SETLENGTH(ADRESA2,DLINA_A2+2);
SETLENGTH(ADRESA3,DLINA_A2+2);
ADRESA2[0]:=1;
ADRESA2[1]:=X64;
ADRESA3[1]:=0;
C2:=0;
FOR E2:=1 TO X64 DO BEGIN
                    IF QQ3[E2] IN [10,13]=FALSE THEN GOTO 5;
                    IF QQ3[E2+1]<>36 THEN GOTO 5;
                    INC(C2);
                    IF C2>DLINA_A2 THEN BEGIN
                                        DLINA_A2:=DLINA_A2+2000;
                                        SETLENGTH(ADRESA2,DLINA_A2+2);
                                        SETLENGTH(ADRESA3,DLINA_A2+2);
                                        END;
                    ADRESA2[0]:=C2;
                    ADRESA2[C2]:=E2;
                    ADRESA3[C2]:=0;
5:
                    END;

FOR I2:=0 TO KOLP-1 DO BEGIN
                       Z5[I2]:='';
                       FOR C2:=1 TO ADRESA2[0] DO BEGIN
                                          IF ADRESA3[C2]=1 THEN GOTO 2;
                                          E2:=ADRESA2[C2];
                                          FOR R2:=1 TO LENGTH(S5[I2]) DO BEGIN
                                              IF QQ3[E2+R2+1]<>ORD(S5[I2,R2]) THEN GOTO 2;
                                              IF QQ3[E2+R2+1]=39 THEN BEGIN
                                                                      Y2:=1;
                                                                      ADRESA3[C2]:=1;
                                                                      FOR T2:=R2+1 TO X64 DO BEGIN
                                                                                             IF QQ3[E2+T2+1] IN [10,13] THEN GOTO 1;
                                                                                             Z5[I2]:=Z5[I2]+CHR(QQ3[E2+T2+1]);
                                                                                             IF QQ3[E2+T2+1]=39 THEN GOTO 1;
                                                                                             INC(Y2);
                                                                                             END;
                                                                      GOTO 1;
                                                                      END;
                                                                         END;
2:
                                                END;
1:
                       END;
99:
CITALNIK:=TRUE;
100:
SYSUTILS.FILECLOSE(Z64);
101:
END;

Ну и где тут чушь? Даже баг sysutils учтён. Грузит данные из файла прекрасно, классы тут не нужны от слова совсем. Лепить кучу классов чтобы не использовать гото в цикле это маразм.
Давай сюда пример, где с goto проще, чем с таким «паттерном „состояние“» (или как это называется).

Когда все эти три комнаты существуют одновременно, в каждой из них кипит жизнь, но рисуется на экране лишь одна. Просто запустить поле класса в таком случае недостаточно, необходимо ещё наладить асинхронную обработку самогенерирующихся событий. Ты описал мыльное кино уровня Диззи, только с более лучшей графикой.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение zub » 06.12.2020 17:18:40

0_0 - глаза вытекли((
Что данный код должен делать? вникать в это - извиняй))

>>SETLENGTH(QQ3,X64+200);
>>DLINA_A2:=DLINA_A2+2000;
Ума не приложу что это (200, 2000)? "хвостики" для защиты от переполнения))? а если всеравно нехватит?
ИМХО это эталон говнокода
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 06.12.2020 17:51:33

zub писал(а):0_0 - глаза вытекли((
Что данный код должен делать? вникать в это - извиняй))


Получает в массиве строк список заголовков строк, читает файл, ищет там строки с такими заголовками(начинаться они должны с маркера конца предыдущей строки, поэтому в первой строке файла пишется не ценная инфа, а приветы знакомым, как в поле чудес), а после распихивает нужную инфлрмацию по другому массиву строк, из которых процедура вызывающая эжту функцию распихуевает их по переменным. Типа такой файл читается:
Код: Выделить всё
ewfkwefkljwefkljfewkljfkljfrkljfkjl  ewfklkljfew
$QWERTY1='12,32443,54,0,0,0,0,0,0, ..... ХОТЬ 100 КИЛОБАЙТ В СТРОКЕ'
$QWERTY2='1'
......

Код: Выделить всё
>>SETLENGTH(QQ3,X64+200);
>>DLINA_A2:=DLINA_A2+2000;
Ума не приложу что это (200, 2000)? "хвостики" для защиты от переполнения))? а если всеравно нехватит?
ИМХО это эталон говнокода

Не от переполнения, а от чтения циклами следующего за текущим элемента, количество которых неизвестно. Хватает всегда, потому что пока нету чисел больше 200 десятичных знаков. Норм всё работает, в отличии от чтения сисутилсом отсутствующих файлов.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение runewalsh » 06.12.2020 17:55:15

Сквозняк писал(а):Когда все эти три комнаты существуют одновременно, в каждой из них кипит жизнь, но рисуется на экране лишь одна.

Не, ну ты серьёзно? Это ж целых две строчки дописать:
Код: Выделить всё
type
   TGame = class
      scenes: array of TScene; // все комнаты
      currentScene: TScene; // «текущая» — рисуемая на экране
   end;

var
   game: TGame;

while not game.Finished do
begin
   game.ProcessScenes; // делает for scene in game.scenes do scene.Process — обрабатывает кипение жизни в комнатах
   game.currentScene.Draw;
   readln(cmd);
   game.currentScene.HandleCommand(cmd);
end;
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 06.12.2020 18:22:10

runewalsh писал(а):Не, ну ты серьёзно? Это ж целых две строчки дописать:

Вся жизнь кучи сущностей у тебя в две строчки уместилась - тебе бы архиваторы писать, но боюсь возникнут проблемы с распаковкой настолько эффективно пожатых файлов.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение runewalsh » 06.12.2020 18:38:56

Всё верно, жизнь кучи сущностей — это
Код: Выделить всё
for сущность in сущности do сущность.жить()

В чём проблема и при чём здесь архиваторы вообще? Напоминаю постановку задачи, а то ты сам забыл:
Сквозняк писал(а):все эти три комнаты существуют одновременно, в каждой из них кипит жизнь, но рисуется на экране лишь одна

Это буквально перекладывается на модификацию первой версии кода как «сделай массив комнат, обрабатывай все, рисуй одну». Goto всё ещё не нужен, невиданной сложности всё ещё не уловил.

Сквозняк писал(а):Ну и где тут чушь?

Скажем так, у тебя навыки и культура программирования как у моего кота (а ведь у меня даже нет кота), код не читается человеком, решает 10 задач одновременно и т. п. Вот так ведь намного лучше:
Код: Выделить всё
{$mode objfpc} {$h+}
uses
   SysUtils;

type
   TKeyValue = record
      key: string;
      value: string;
   end;
   TKeyValueList = array of TKeyValue;

   function ReadFileAsString(const fn: string): string;
   var
      f: THandle;
      sz: int64;
   begin
      f := FileOpen(fn, fmOpenRead);
      if f = THandle(-1) then RaiseLastOSError;
      try
         sz := FileSeek(f, int64(0), fsFromEnd);
         if sz < 0 then RaiseLastOSError;
         SetLength(result, sz);

         if FileSeek(f, 0, fsFromBeginning) < 0 then RaiseLastOSError;
         sz := FileRead(f, pointer(result)^, sz);
         if sz < 0 then RaiseLastOSError;

         SetLength(result, sz);
      finally
         FileClose(f);
      end;
   end;

   // Сканирование подстроки вида $ключ='значение'.
   procedure ParseKeyValue(const s: string; var p: SizeInt; var kv: TKeyValue);
   var
      start: SizeInt;
   begin
      Assert(s[p] = '$');
      inc(p);

      start := p;
      while p <= length(s) do
         case s[p] of
            ' ', '=': break;
            else inc(p);
         end;
      kv.key := Copy(s, start, p - start);

      while (p <= length(s)) and (s[p] = ' ') do inc(p);
      if not ((p <= length(s)) and (s[p] = '=')) then raise Exception.Create('Ожидается =.');
      inc(p);
      while (p <= length(s)) and (s[p] = ' ') do inc(p);
      if not ((p <= length(s)) and (s[p] = '''')) then raise Exception.Create('Ожидается ''.');
      inc(p);

      start := p;
      while (p <= length(s)) and (s[p] <> '''') do inc(p);
      if not ((p <= length(s)) and (s[p] = '''')) then raise Exception.Create('Ожидается закрывающая ''.');
      kv.value := Copy(s, start, p - start);
      inc(p);
   end;

   function ParseKeyValues(const s: string): TKeyValueList;
   var
      p, nR: SizeInt;
   begin
      nR := 0;
      result := nil;
      p := 1;
      while p <= length(s) do
      begin
         case s[p] of
            #13, #10, ' ': inc(p);
            '$':
               begin
                  inc(nR);
                  if nR > length(result) then SetLength(result, nR + 4 + nR div 4 + nR div 8);
                  ParseKeyValue(s, p, result[nR - 1]);
               end;
            else
               begin
                  // Пропуск до конца строки.
                  inc(p);
                  while p <= length(s) do
                     case s[p] of
                        #13, #10: break;
                        else inc(p);
                     end;
               end;
         end;
      end;
      SetLength(result, nR);
   end;

   function Contains(const filterKeys: array of string; const key: string): boolean;
   var
      i: SizeInt;
   begin
      for i := 0 to High(filterKeys) do
         if key = filterKeys[i] then
            exit(true);
      result := false;
   end;

   function FilterKeyValues(const kv: array of TKeyValue; const filterKeys: array of string): TKeyValueList;
   var
      i, nR: SizeInt;
   begin
      nR := 0;
      result := nil;
      for i := 0 to High(kv) do
         if Contains(filterKeys, kv[i].key) then
         begin
            inc(nR);
            if nR > length(result) then SetLength(result, nR + 4 + nR div 4 + nR div 8);
            result[nR - 1] := kv[i];
         end;
      SetLength(result, nR);
   end;

var
   kv: TKeyValue;

begin
   for kv in FilterKeyValues(ParseKeyValues(ReadFileAsString('data.txt')), ['name', 'weapon']) do
      writeln(kv.key, '=', kv.value);
end.

Для файла с содержимым
Код: Выделить всё
$name = 'werewolf'
$hit_points = '500'
$weapon = 'claws'

это выдаст
Код: Выделить всё
name=werewolf
weapon=claws

Но в отличие от твоего, код можно поддерживать, переиспользовать (например, сделать с содержимым файла что-либо кроме фильтрации по именам лол) и вот это всё.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 06.12.2020 19:34:35

runewalsh писал(а):Всё верно, жизнь кучи сущностей — это

Код: Выделить всё
for сущность in сущности do сущность.жить()


В чём проблема и при чём здесь архиваторы вообще? Напоминаю постановку задачи, а то ты сам забыл:

Сквозняк писал(а):
все эти три комнаты существуют одновременно, в каждой из них кипит жизнь, но рисуется на экране лишь одна


Это буквально перекладывается на модификацию первой версии кода как «сделай массив комнат, обрабатывай все, рисуй одну». Goto всё ещё не нужен, невиданной сложности всё ещё не уловил.

Юморист, жги дальше. Внутри цикла обработки логики будет жуткий трэш и угар, фактически операционная система. Сущности будут слать друг другу асинхронные запросы, пересылать пакеты данных - кентам же надо видеть мир, кто-то следить за правильностью постановки задач. И если логика станет тормозить графику, то надо бы её вынести в отдельный поток, чтобы фпс не падало, тогда графика будет лишь иногда дёргаться но не тормозить. А то что ты представил, это недалеко от Диззи ушло, только графона на уровне ААА добавили.

runewalsh писал(а):Скажем так, у тебя навыки и культура программирования как у моего кота (а ведь у меня даже нет кота), код не читается человеком,

А мне и не нужно чтобы арабы с евреями в том коде разбирались, такой задачи и не стояло. Покажи где у тебя в паспорте записано что ты есть человек :mrgreen: Это раввин решать будеь, человек ты или как, вполне возможно он решит что твой кот к человекам ближе. А в паспорте написано что ты гражданин и подразумевается что принадлежишь к людям. Даже в конституции РФ есть права человека, а есть людей/граждан.

Добавлено спустя 18 минут 59 секунд:
runewalsh писал(а):решает 10 задач одновременно и т. п.

Он решает одну задачу - в вызывающей процедуре занимать одну строчку, типа
Код: Выделить всё
if citalnik(........) = false then goto 100;

runewalsh писал(а):Вот так ведь намного лучше:

Код: Выделить всё
{$mode objfpc} {$h+}
uses
SysUtils;

type
TKeyValue = record
key: string;
value: string;
end;
TKeyValueList = array of TKeyValue;

function ReadFileAsString(const fn: string): string;
var
f: THandle;
sz: int64;
begin
f := FileOpen(fn, fmOpenRead);
if f = THandle(-1) then RaiseLastOSError;
try
sz := FileSeek(f, int64(0), fsFromEnd);
if sz < 0 then RaiseLastOSError;
SetLength(result, sz);

if FileSeek(f, 0, fsFromBeginning) < 0 then RaiseLastOSError;
sz := FileRead(f, pointer(result)^, sz);
if sz < 0 then RaiseLastOSError;

SetLength(result, sz);
finally
FileClose(f);
end;
end;

// Сканирование подстроки вида $ключ='значение'.
procedure ParseKeyValue(const s: string; var p: SizeInt; var kv: TKeyValue);
var
start: SizeInt;
begin
Assert(s[p] = '$');
inc(p);

start := p;
while p <= length(s) do
case s[p] of
' ', '=': break;
else inc(p);
end;
kv.key := Copy(s, start, p - start);

while (p <= length(s)) and (s[p] = ' ') do inc(p);
if not ((p <= length(s)) and (s[p] = '=')) then raise Exception.Create('Ожидается =.');
inc(p);
while (p <= length(s)) and (s[p] = ' ') do inc(p);
if not ((p <= length(s)) and (s[p] = '''')) then raise Exception.Create('Ожидается ''.');
inc(p);

start := p;
while (p <= length(s)) and (s[p] <> '''') do inc(p);
if not ((p <= length(s)) and (s[p] = '''')) then raise Exception.Create('Ожидается закрывающая ''.');
kv.value := Copy(s, start, p - start);
inc(p);
end;

function ParseKeyValues(const s: string): TKeyValueList;
var
p, nR: SizeInt;
begin
nR := 0;
result := nil;
p := 1;
while p <= length(s) do
begin
case s[p] of
#13, #10, ' ': inc(p);
'$':
begin
inc(nR);
if nR > length(result) then SetLength(result, nR + 4 + nR div 4 + nR div 8);
ParseKeyValue(s, p, result[nR - 1]);
end;
else
begin
// Пропуск до конца строки.
inc(p);
while p <= length(s) do
case s[p] of
#13, #10: break;
else inc(p);
end;
end;
end;
end;
SetLength(result, nR);
end;

function Contains(const filterKeys: array of string; const key: string): boolean;
var
i: SizeInt;
begin
for i := 0 to High(filterKeys) do
if key = filterKeys[i] then
exit(true);
result := false;
end;

function FilterKeyValues(const kv: array of TKeyValue; const filterKeys: array of string): TKeyValueList;
var
i, nR: SizeInt;
begin
nR := 0;
result := nil;
for i := 0 to High(kv) do
if Contains(filterKeys, kv[i].key) then
begin
inc(nR);
if nR > length(result) then SetLength(result, nR + 4 + nR div 4 + nR div 8);
result[nR - 1] := kv[i];
end;
SetLength(result, nR);
end;

var
kv: TKeyValue;

begin
for kv in FilterKeyValues(ParseKeyValues(ReadFileAsString('data.txt')), ['name', 'weapon']) do
writeln(kv.key, '=', kv.value);
end.

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

runewalsh писал(а):Но в отличие от твоего, код можно поддерживать, переиспользовать (например, сделать с содержимым файла что-либо кроме фильтрации по именам лол) и вот это всё.

Ты его не только поддержать, ты его зарелизить нормально не смог потому что теоретизируешь. А мой код взялся не из фантазии, он вырезан из другой процедуры, которая уже работала, потому делает то, что надо. И поддерживается он нормально, а в твоём проблема на проблеме, может человеками он и лучше читается, но вот людьми - однозначно нет.
Последний раз редактировалось Сквозняк 06.12.2020 19:54:35, всего редактировалось 1 раз.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение runewalsh » 06.12.2020 19:53:37

Сквозняк писал(а):Внутри цикла обработки логики будет жуткий трэш и угар, фактически операционная система.

Это здесь ни при чём и ты сам не знаешь, о чём говоришь, здесь ТОЖЕ ничего сложного нет и идеи можно описать в двух строчках.

Ты, кстати, не первый, кто пытается пугать меня сложностью, здесь на форуме когда-то давно был челик, не настолько упоротый, но тоже очень СТРАННЫЙ, который говорил о том, что разрабатыаает очень сложные приложения, в которых я ничего не понимаю, и привязывал это к тому, что, дескать, UTF-8 придумали лентяи, которым выделили деньги на перевод приложения на Юникод, и они придумали UTF-8, чтобы эти деньги попилить и отчитаться: «а у нас и так всё в Юникоде))». Подтекст был в том, что сложные, во всяком случае, сложно звучащие задачи требуют сложных, непонятных решений с перелопачиванием всего кода, в частности, перевод на Юникод — как минимум замены везде string на widestring и последующей ловли багов во всех местах, завязанных на char=ansichar. Мерило работы — усталость!

Сквозняк писал(а):Покажи где у тебя в паспорте записано что ты есть человек :mrgreen:

Так я-то рептилоид, о людях со стороны рассуждаю, именно поэтому моё мнение о людях и качественнее (объективнее).

Сквозняк писал(а):Да дерьмо это. Там даже баг сисутилса на чтение несуществующего файла неучтёню

Это 2 строчки добавить, суть не в этом, я намеренно опустил, потому что о баге первый раз слышу и в проверке размера смысла тоже не вижу: ты не обрабатываешь примерно 100500 куда более насущных вещей, типа ошибок (опечаток) в разметке, чтобы о размере думать.
Последний раз редактировалось runewalsh 06.12.2020 20:04:49, всего редактировалось 1 раз.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 06.12.2020 20:03:38

runewalsh писал(а):Это здесь ни при чём и ты сам не знаешь, о чём говоришь, здесь ТОЖЕ ничего сложного нет и идеи можно описать в двух строчках.

Именно я хорошо этот угар знаю, а ты сказки рассказываешь.
runewalsh писал(а): UTF-8 придумали лентяи

Именно так. Буржуи оставили у себя однобайтную кодировку, а со многобайтными пусть трахается остальной мир. И ведь лажа с её поддержкой происходит постоянно. В ОС даже шрифт включающий все её буквы в одном файле до сих пор не запилили. На сайте эмплаера был такой файлик на 20+ метров. В плеере отлично работает, а вот если его добавить в опереционку, то не в каждой после этого рисовка букв остаётся работоспособной. Система давится файлом содержащим всю utf8! Да даже в лазарусе, копипастишь из браузера некоторые значки из utf8 а потом на форме они превращаются в квадратики с цифрой. Ахрененно utf8 поддержана.
runewalsh писал(а):Так я-то рептилоид, о людях со стороны рассуждаю, именно поэтому моё мнение о людях и качественнее (объективнее).


Качественно не может быть. Вас позже произвели, ещё мутации не устаканились.

Добавлено спустя 2 минуты 10 секунд:
runewalsh писал(а):Это 2 строчки добавить, суть не в этом, я намеренно опустил, потому что о баге первый раз слышу и в проверке размера смысла тоже не вижу: ты не обрабатываешь примерно 100500 куда более насущных вещей, типа ошибок в разметке самого файла, прежде чем о размере думать.

А мой код эти ошибки в разметке файла обрабатывает мимоходом и выносит решение. И лучше лишняя проверка от лажи, чем если она случится.

Добавлено спустя 3 минуты 7 секунд:
Касательно проверки размера файла. Когда-то на хрюше развлекался. На файле в который другим операторам компа не нужно лазить, а там размер в десятки мегабайт был, ставил расширение открываемое вордом. Читайте и ловите жестокий повисон :D О размере думать нужно.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение runewalsh » 06.12.2020 20:49:09

Сквозняк писал(а):Именно я хорошо этот угар знаю, а ты сказки рассказываешь.

Один раз попробовал написать цикл сообщений через goto, не получилось и теперь всем рассказываешь про треш, угар и операционные системы? Понимаю.

Вообще я ж это не сейчас придумал. Когда мы с тем челиком с квестом разговаривали, я сделал для иллюстрации свой — с оБрАбАтЫвАеМыМи комнатами и вот этим всем. Я его не показываю только потому, что там непристойности.

Сквозняк писал(а):А мой код эти ошибки в разметке файла обрабатывает мимоходом

Называй вещи своими словами, он их вообще не обрабатывает. Я тоже раньше выдавал необрабатывание ошибок за особый путь и «вынепонимаете, это обработка м и м о х о д о м».
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 06.12.2020 21:56:59

runewalsh писал(а):Один раз попробовал написать цикл сообщений через goto, не получилось и теперь всем рассказываешь про треш, угар и операционные системы? Понимаю.

Не получиться гото может только у неосиляторов с дыркой в зннаниях. один раз у тебя не получилось использовать гото и теперь всем рассказываешь какое оно плохое. Погроммисты не зря придумали машинное обучение, которое даёт непредсказуемый результат - так они пытаются обойти трэш и угар при программировании логики. Но ты по ходу считаешь себя самым умным - всё у тебя просто, в две строчки :mrgreen:

runewalsh писал(а):Называй вещи своими словами, он их вообще не обрабатывает. Я тоже раньше выдавал необрабатывание ошибок за особый путь и «вынепонимаете, это обработка м и м о х о д о м».

Если называть вещи своими именами, то ты нихрена не разобрался в _одной_ функции с гото, не смог с ходу написать адекватную замену, хотя никто об этом и не просил, и теперь несёшь чушь. Вглядись в ту функцию внимательно. Она отбирает для дальнейшего использования только строки соответствующие формату и с запрошенным заголовком. В прочих строках можно хоть комменты писать без всякой разметки. Такова особенность формата данных. Очень удобно при чтении неизменяемых программой конфигов.
Сквозняк
энтузиаст
 
Сообщения: 1109
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение runewalsh » 06.12.2020 22:12:36

Покажи пример, именно рабочий код, который, используя функцию CITALNIK, фильтрует из файла
Код: Выделить всё
$name='werewolf'
$hit_points='500'
$weapon='claws'

значения name и weapon.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 06.12.2020 22:22:09

Сквозняк писал(а):
Код: Выделить всё
FUNCTION CITALNIK(IMJA_FAILA_SOHRANKI5: ANSISTRING;VAR S5: ARRAY OF STRING; VAR Z5: ARRAY OF ANSISTRING;LIMIT: LONGINT): BOOLEAN;
VAR
DLINA_A2: LONGINT=1000;
QQ3,ADRESA3: ARRAY OF BYTE;
ADRESA2: ARRAY OF LONGINT;
M2,E2,C2,I2,R2,Y2,T2: LONGINT;
KOLP: LONGINT;
X64: INT64;
{$IFNDEF LINUX}
Z64: SYSUTILS.THANDLE;
{$ENDIF}
{$IFDEF LINUX}
Z64: INT64;
{$ENDIF LINUX}
LABEL
1,2,5,  99,100,101;
BEGIN
CITALNIK:=FALSE;
{$IFDEF WINDOWS}
IMJA_FAILA_SOHRANKI5:=PUTI_MAZDAJA(IMJA_FAILA_SOHRANKI5);
{$ENDIF WINDOWS}
IF PADLOFAIL(IMJA_FAILA_SOHRANKI5)=FALSE THEN GOTO 101;
KOLP:=LENGTH(S5);
Z64:=SYSUTILS.FILEOPEN(IMJA_FAILA_SOHRANKI5, fmOpenRead);
IF Z64=VINDOFAILOBAG THEN GOTO 100; //КОНСТАНТА ЕСТЬ ДЛЯ ЛИНУКСА, ВИН32 И ВИН64
X64:=SYSUTILS.FILESEEK(Z64,0,2);
SYSUTILS.FILESEEK(Z64,0,0);
IF X64>LIMIT THEN X64:=LIMIT;
IF X64<1 THEN GOTO 99;
SETLENGTH(QQ3,X64+200);
FOR M2:=X64 TO X64+200-1 DO QQ3[M2]:=0;
M2:=X64;
E2:=0;
SYSUTILS.FILEREAD(Z64,QQ3[1],X64);
SETLENGTH(ADRESA2,DLINA_A2+2);
SETLENGTH(ADRESA3,DLINA_A2+2);
ADRESA2[0]:=1;
ADRESA2[1]:=X64;
ADRESA3[1]:=0;
C2:=0;
FOR E2:=1 TO X64 DO BEGIN
                    IF QQ3[E2] IN [10,13]=FALSE THEN GOTO 5;
                    IF QQ3[E2+1]<>36 THEN GOTO 5;
                    INC(C2);
                    IF C2>DLINA_A2 THEN BEGIN
                                        DLINA_A2:=DLINA_A2+2000;
                                        SETLENGTH(ADRESA2,DLINA_A2+2);
                                        SETLENGTH(ADRESA3,DLINA_A2+2);
                                        END;
                    ADRESA2[0]:=C2;
                    ADRESA2[C2]:=E2;
                    ADRESA3[C2]:=0;
5:
                    END;

FOR I2:=0 TO KOLP-1 DO BEGIN
                       Z5[I2]:='';
                       FOR C2:=1 TO ADRESA2[0] DO BEGIN
                                          IF ADRESA3[C2]=1 THEN GOTO 2;
                                          E2:=ADRESA2[C2];
                                          FOR R2:=1 TO LENGTH(S5[I2]) DO BEGIN
                                              IF QQ3[E2+R2+1]<>ORD(S5[I2,R2]) THEN GOTO 2;
                                              IF QQ3[E2+R2+1]=39 THEN BEGIN
                                                                      Y2:=1;
                                                                      ADRESA3[C2]:=1;
                                                                      FOR T2:=R2+1 TO X64 DO BEGIN
                                                                                             IF QQ3[E2+T2+1] IN [10,13] THEN GOTO 1;
                                                                                             Z5[I2]:=Z5[I2]+CHR(QQ3[E2+T2+1]);
                                                                                             IF QQ3[E2+T2+1]=39 THEN GOTO 1;
                                                                                             INC(Y2);
                                                                                             END;
                                                                      GOTO 1;
                                                                      END;
                                                                         END;
2:
                                                END;
1:
                       END;
99:
CITALNIK:=TRUE;
100:
SYSUTILS.FILECLOSE(Z64);
101:
END;


не очень читабельно, но более-менее похоже на правду.

Добавлено спустя 2 минуты 27 секунд:
runewalsh писал(а):Всё верно, жизнь кучи сущностей — это
Вот так ведь намного лучше:
Код: Выделить всё
{$mode objfpc} {$h+}
uses
   SysUtils;

type
   TKeyValue = record
      key: string;
      value: string;
   end;
   TKeyValueList = array of TKeyValue;

   function ReadFileAsString(const fn: string): string;
   var
      f: THandle;
      sz: int64;
   begin
      f := FileOpen(fn, fmOpenRead);
      if f = THandle(-1) then RaiseLastOSError;
      try
         sz := FileSeek(f, int64(0), fsFromEnd);
         if sz < 0 then RaiseLastOSError;
         SetLength(result, sz);

         if FileSeek(f, 0, fsFromBeginning) < 0 then RaiseLastOSError;
         sz := FileRead(f, pointer(result)^, sz);
         if sz < 0 then RaiseLastOSError;

         SetLength(result, sz);
      finally
         FileClose(f);
      end;
   end;

   // Сканирование подстроки вида $ключ='значение'.
   procedure ParseKeyValue(const s: string; var p: SizeInt; var kv: TKeyValue);
   var
      start: SizeInt;
   begin
      Assert(s[p] = '$');
      inc(p);

      start := p;
      while p <= length(s) do
         case s[p] of
            ' ', '=': break;
            else inc(p);
         end;
      kv.key := Copy(s, start, p - start);

      while (p <= length(s)) and (s[p] = ' ') do inc(p);
      if not ((p <= length(s)) and (s[p] = '=')) then raise Exception.Create('Ожидается =.');
      inc(p);
      while (p <= length(s)) and (s[p] = ' ') do inc(p);
      if not ((p <= length(s)) and (s[p] = '''')) then raise Exception.Create('Ожидается ''.');
      inc(p);

      start := p;
      while (p <= length(s)) and (s[p] <> '''') do inc(p);
      if not ((p <= length(s)) and (s[p] = '''')) then raise Exception.Create('Ожидается закрывающая ''.');
      kv.value := Copy(s, start, p - start);
      inc(p);
   end;

   function ParseKeyValues(const s: string): TKeyValueList;
   var
      p, nR: SizeInt;
   begin
      nR := 0;
      result := nil;
      p := 1;
      while p <= length(s) do
      begin
         case s[p] of
            #13, #10, ' ': inc(p);
            '$':
               begin
                  inc(nR);
                  if nR > length(result) then SetLength(result, nR + 4 + nR div 4 + nR div 8);
                  ParseKeyValue(s, p, result[nR - 1]);
               end;
            else
               begin
                  // Пропуск до конца строки.
                  inc(p);
                  while p <= length(s) do
                     case s[p] of
                        #13, #10: break;
                        else inc(p);
                     end;
               end;
         end;
      end;
      SetLength(result, nR);
   end;

   function Contains(const filterKeys: array of string; const key: string): boolean;
   var
      i: SizeInt;
   begin
      for i := 0 to High(filterKeys) do
         if key = filterKeys[i] then
            exit(true);
      result := false;
   end;

   function FilterKeyValues(const kv: array of TKeyValue; const filterKeys: array of string): TKeyValueList;
   var
      i, nR: SizeInt;
   begin
      nR := 0;
      result := nil;
      for i := 0 to High(kv) do
         if Contains(filterKeys, kv[i].key) then
         begin
            inc(nR);
            if nR > length(result) then SetLength(result, nR + 4 + nR div 4 + nR div 8);
            result[nR - 1] := kv[i];
         end;
      SetLength(result, nR);
   end;

var
   kv: TKeyValue;

begin
   for kv in FilterKeyValues(ParseKeyValues(ReadFileAsString('data.txt')), ['name', 'weapon']) do
      writeln(kv.key, '=', kv.value);
end.


то есть, ты считаешь, что не тестированный код в самом деле лучше протестированного? Хоть и плохо читаемого.

:idea: Вообще, мне кто-то писал, что не выкладывает не тестированный код... а тут...
Seenkao
энтузиаст
 
Сообщения: 502
Зарегистрирован: 01.04.2020 03:37:12

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение runewalsh » 06.12.2020 22:27:15

(А, я вас перепутал опять.)
Последний раз редактировалось runewalsh 06.12.2020 22:38:49, всего редактировалось 1 раз.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 06.12.2020 22:28:15

runewalsh писал(а):
Код: Выделить всё
begin
      f := FileOpen(fn, fmOpenRead);
      if f = THandle(-1) then RaiseLastOSError;
      try
         sz := FileSeek(f, int64(0), fsFromEnd);
         if sz < 0 then RaiseLastOSError;
         SetLength(result, sz);

         if FileSeek(f, 0, fsFromBeginning) < 0 then RaiseLastOSError;
         sz := FileRead(f, pointer(result)^, sz);
         if sz < 0 then RaiseLastOSError;

         SetLength(result, sz);
      finally
         FileClose(f);
      end;
   end;

а выход где, если ошибка? (или RaiseLastOSError - за нас всё делает???)

тут ошибси я.... :!:
runewalsh писал(а):
Код: Выделить всё
while p <= length(s) do
         case s[p] of
            ' ', '=': break;
            else inc(p);
         end;
то есть просто взяли и зависли на ровном месте?
Seenkao
энтузиаст
 
Сообщения: 502
Зарегистрирован: 01.04.2020 03:37:12

Пред.След.

Вернуться в Потрепаться

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21

Рейтинг@Mail.ru