BG Development


Страници: (2) [1] 2   ( Първото ново мнение ) Reply to this topicStart new topicStart Poll

> Универсална обработка на CR/LF, Как го правя аз.
johnfound
Публикувано на: 10-06-2018, 11:44
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6705
Регистриран на: 27.05.04



Като пиша програми за текстообработка, никога не съм харесвал различните варианти за край на реда. Още повече ме дразни да поддържам всички едновременно, дали като опции за потребителя, дали като автоматично детектиране.

Затова навсякъде в моите програми, където трябва да чета текстови файлове и да ги разделям на редове използвам следният много прост алгоритъм:

CODE

start = 0;
for i = 0 to text.length-1
 if text[i] in [13, 10] then
    process_line(start, i);
    if text[i+1] == text[i] xor 7 then i = i + 1;
    start = i+1;
 end if
end for


По този начин, се обработват (почти) правилно всички използвани и неизползвани досега комбинации, но които могат да се породят от нечий болен мозък. Примерно:

CR CR CR – три реда в MAC кодиране.
LF LF LF - три реда в UNIX кодиране.
CR LF CR LF CR LF – три реда в DOS/Windows кодиране.
LF CR LF CR LF CR – три реда в съвършено екзотичната кодировка на BBC Micro
CR CR LF LF – три реда в смесено кодиране – MAC, DOS, UNIX.

Сега, последния пример може да е малко спорен – примерно да се интерпретира като 4 реда, два от които в MAC и два в UNIX, но всъщност, ако някой идиот е създал файл със смесени кодировки, той определено няма думата по това как да се интерпретират тези символи. icon_lol.gif

Затова пък, алгоритмите стават абсолютно нечувствителни към кодировката за край на реда. Бързодействието се повлиява минимално – буквално две инструкции повече, които са по-малко, отколкото ако на функциите се подава като параметър каква е кодировката за край на ред.

Това мнение е било редактирано от johnfound на 10-06-2018, 13:09


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
ici
Публикувано на: 10-06-2018, 12:12
Quote Post


Group Icon
Име: Ивайло Илчев ики
Група: VIP
Ранг: Почетен член

Мнения: 15599
Регистриран на: 06.06.04



Аз се срещам с подобен казус за комуникация през терминал. Символите може да идват един по един, може на блокове. Просто игнорирам CR и обработвам LF.


--------------------
Както и при християнската религия, така и при социализмът, най-лошата реклама за идеята са нейните последователи. - Джордж Оруел
PMEmail PosterUsers Website
Top
Gamma Goblin
Публикувано на: 10-06-2018, 12:34
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 1230
Регистриран на: 21.02.18



най-лесно и правилно е да ползваш линукския вариант, и да не се занимаваш с бози


--------------------
Напред! Живота е сраженье! Напред! И прав всегда ходи!
Напред, макар към поражение! Ако ще паднеш, прав падни!
---
Raw, and untamed in spirit, We chew this world and Spit it out
---
Challenge my own world to chaos
---
Im not intimidated by the good looking ones, it's the ugly ones that scare the shit out of me
PMEmail PosterUsers Website
Top
johnfound
Публикувано на: 10-06-2018, 12:42
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6705
Регистриран на: 27.05.04



QUOTE (Gamma Goblin @ 10-06-2018, 13:34)
най-лесно и правилно е да ползваш линукския вариант, и да не се занимаваш с бози

Ами не, това е вариант ако говорим за записване на файлове. Но за четенето въпросът не стои така.


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
AK-85
Публикувано на: 10-06-2018, 12:52
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 775
Регистриран на: 06.07.06



"start = i;" не трябва ли да е "start = i + 1;"? В противен случай ако входът е "ab\n12\n", ще има извикване на process_line(0, 2) и process_line(2, 5), т.е. редът във второто извикване започва със знак за нов ред.

Иначе и при обработка на HTTP също няма избор.
PM
Top
SuN
Публикувано на: 10-06-2018, 12:53
Quote Post


Group Icon
Име:
Група: Администратор
Ранг: Почетен член

Мнения: 6839
Регистриран на: 27.01.05



QUOTE (johnfound @ 10-06-2018, 11:44)
CODE

start = 0;
for i = 0 to text.length-1
 if text[i] in [13, 10] then
    process_line(start, i);
    if text[i+1] == text[i] xor 7 then i = i + 1;
    start = i;
 end if
end for


Нищо не се разбира. Може ли да го напишеш на асемблер?


--------------------
Копирай лесно ударено и - ѝ Ѝ
Замърсяване на въздуха в София - http://aqicn.org/city/bulgaria/sofia/druzhba/
PMEmail Poster
Top
relax4o
Публикувано на: 10-06-2018, 13:12
Quote Post



Име:
Група: Потребител
Ранг: Почетен член

Мнения: 2079
Регистриран на: 04.04.07



QUOTE (AK-85 @ 10-06-2018, 12:52)
"start = i;" не трябва ли да е "start = i + 1;"? В противен случай ако входът е "ab\n12\n", ще има извикване на process_line(0, 2) и process_line(2, 5), т.е. редът във второто извикване започва със знак за нов ред.

Иначе и при обработка на HTTP също няма избор.

then i = i + 1;


--------------------
Бисери :D

QUOTE (oveRLuckEd)
Ползваш някоя нова версия на PHP, която е вече ооп ориентирана и заради това ти я изкарва тази грешка.


QUOTE (nbacool2)
Щом няма input полета, значи няма откъде да се направи SQL инжекция Very Happy
PM
Top
johnfound
Публикувано на: 10-06-2018, 13:14
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6705
Регистриран на: 27.05.04



QUOTE (AK-85 @ 10-06-2018, 13:52)
"start = i;" не трябва ли да е "start = i + 1;"? В противен случай ако входът е "ab\n12\n", ще има извикване на process_line(0, 2) и process_line(2, 5), т.е. редът във второто извикване започва със знак за нов ред.

Иначе и при обработка на HTTP също няма избор.

Да, разбира се оправих го. Има и други проблеми, например, трябва още една проверка за дължина на стринга, защото с това i=i+1 лесно може да се излезе след последния символ.

Но в реален код, цикъла няма да е с фиксирана дължина, а докато се срещне 0, така че тази проверка изглежда малко по-друго.

С HTTP е интересен казуса – според стандартите, единственото правилно завършване на ред е CRLF, само че много програми го игнорират това и си генерират само LF. Затова и при HTTP е добре да се обработва по-гъвкаво.


--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
johnfound
Публикувано на: 10-06-2018, 13:30
Quote Post


Group Icon
Име:
Група: VIP
Ранг: Почетен член

Мнения: 6705
Регистриран на: 27.05.04



QUOTE (SuN @ 10-06-2018, 13:53)
Нищо не се разбира. Може ли да го напишеш на асемблер?

Ето ти фрагмент от реален код:

CODE

;...................... някакъв код

.scan_line:
       lodsb

       cmp     al, $0d
       je      .end_of_line
       cmp     al, $0a
       je      .end_of_line
       test    al, al
       jz      .end_of_file     ; последна линия и файла завършва...

;........................... някакъв друг код за обработка на текста в линията ...........

.end_of_line:

       xor     al, $0d xor $0a
       cmp    [esi], al
       jne     .line_ok
       inc     esi
.line_ok:

;.............. Правим нещо на края на линията... esi сочи в началото на следващата.

      jmp  .scan_line



--------------------
asm32 - Приложно програмиране на асемблер.
Tox: 2B446ADCEC7E180CD4C59391D81D4CAB3E99CA7AE767DB3AB45AF976F8A2050FF071DDB733F1
PMEmail PosterUsers Website
Top
wqw
Публикувано на: 10-06-2018, 14:00
Quote Post


Group Icon
Име: Владимир Висулчев
Група: VIP
Ранг: Почетен член

Мнения: 5815
Регистриран на: 10.06.04



Това с MAC кодирането не го разбирам честно.

99% от парсърите ползват `\r?\n` за new-line терминал.

cheers,
</wqw>


--------------------
PMEmail PosterUsers Website
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Страници: (2) [1] 2  Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2018 | BG Development | All Rights Reserved
RSS 2.0