Usuwanie znaczników CR w Lazarusie

Usuwanie znaczników CR w Lazarusie
0

Witam

Od niedawna próbuję pisać drobne aplikacje w Lazarusie. Ostatnio napotkałem na problem znaczników końca linii. 
Otóż wczytuję plik generowany przez inną aplikację, który następnie przerabiam w swojej. Plik umieszcza znaczniki końca linii **LF**. W niektórych liniach jednak dodaje w środku linii znacznik **CR**. Wygląda to mniej więcej tak:
Kopiuj
pierwsza linia <LF>
druga linia <LF>
trzecia <CR> linia <LF>
czwarta linia <LF>

W Delphi nie ma problemu, znaczniki CR są pomijane, natomiast Lazarus interpretuje je jako znaczniki końca wiersza.
Chciałbym się pozbyć znaczników CF w pliku. Na tą okoliczność wysmarowałem taką procedurkę (niestety nie działa):

Kopiuj
procedure usun_cr(var plik:TextFile;nazwaPliku:string);
var
  cr:integer;
  ile:byte;
  linia,pom:string;
  tymcz:TStringList;
begin

tymcz:=TstringList.Create;

reset(plik);
cr:=0;
ile:=0;
pom:='';
linia:='';
while not eof(plik) do
  begin

   readln(plik,linia);
   cr:=Pos(#13, linia);
    if cr>0 then
     begin
       inc(ile);
         if ile>1 then
          linia:=pom+linia;
       pom:=linia;
     end//if cr>0
     else
      if ile>0 then
       begin
        linia:=pom+linia;
        ile:=0;
        cr:=0;
       end;//if ile>0

    if (cr=0)and(ile=0) then
    tymcz.Add(linia);
  end;//while not eof(plik)
  
CloseFile(plik);
tymcz.SaveToFile(nazwaPliku);
tymcz.Free;

end;//procedure usun_cr
Procedurę chciałbym używać wielokrotnie, gdyż dość często muszę przerabiać pliki generowane przez zewnętrzną aplikację. Nie jestem zawodowym programistą, zajmuję się raczej administrowaniem siecią, dlatego programowanie jest jedynie uzupełnieniem mojej pracy.
Z góry dzięki za wszelkie sugestie.
flowCRANE
Na przyszłość - wstawiaj kod w odpowiednie znaczniki i zrezygnuj z głupkowatych wcięć - to nie list motywacyjny tylko zwyczajny post :>
0

procedure usun_cr(var plik:TextFile;nazwaPliku:string);

I po co ci zmienna plik?

Kopiuj
readln(plik,linia);
   cr:=Pos(#13, linia);

Tak, jakie to mądre, skoro Lazarus traktuje #13 jako nową linię to najpierw czytajmy linię a potem szukajmy znaku końca linii który jest usuwany w readln. Genialne!

Z góry dzięki za wszelkie sugestie.

Sugestia - zadaj pytanie.

Plik umieszcza znaczniki końca linii LF. W niektórych liniach jednak dodaje w środku linii znacznik CR.

Czy CR jest tam celowo jako przejście nowej linii, jako część danych czy jako CO. W normalnych plikach tekstowych CR występuje jako nowa linia w MAC OS. Dzisiaj się raczej stosuje CRLF albo LF, ale FPC jest zgodny także z CR bo niektóre systemy to stosują.

Podaj jeszcze o jaki OS chodzi bo to tutaj ma znaczenie.

0

Tak, jakie to mądre, skoro Lazarus traktuje #13 jako nową linię to najpierw czytajmy linię a potem szukajmy znaku końca linii który jest usuwany w readln. Genialne!

Przyznaję, że tu może tkwić błąd. Tak, jak pisałem wcześniej aplikacje piszę dorywczo i na własne potrzeby i dlatego być może źle zinterpretowałem to, co Lazarus robi podczas wczytywania linii. Byłem pewny, że nie dodaje znacznika CRLF, a jedynie wczytuje linię w niezmienionej postaci i przechodzi do odczytu nowej linii w pliku.

Czy CR jest tam celowo jako przejście nowej linii, jako część danych czy jako CO. W normalnych plikach tekstowych CR występuje jako nowa linia w MAC OS. Dzisiaj się raczej stosuje CRLF albo LF, ale FPC jest zgodny także z CR bo niektóre systemy to stosują.

Podaj jeszcze o jaki OS chodzi bo to tutaj ma znaczenie.

Tak jak pisałem, plik jest generowany przez zewnętrzną aplikację (opartą na JBOSS w Linuksie) i jest to niezależne ode mnie. Znacznik CR nie powinien się tam znajdować.

Sugestia - zadaj pytanie.

Otóż moje pytanie było w temacie posta - jak pozbyć się znacznika CR w generowanym przez zewnętrzną aplikację pliku.
Być może wystarczy ustawić coś w opcjach Lazarusa, ale niestety nie mogłem niczego sensownego znaleźć.

0

Być może wystarczy ustawić coś w opcjach Lazarusa, ale niestety nie mogłem niczego sensownego znaleźć.

Wątpię.

Otóż moje pytanie było w temacie posta - jak pozbyć się znacznika CR w generowanym przez zewnętrzną aplikację pliku.

Podczas wczytywania czy chcesz go przerobić i puścić dalej? Jeżeli przerobić to wczytuj go bajtowo i usuwaj bajty 13? Jak wczytywanie to zależy jak wczytujesz.
Taka odpowiedź wystarczy? Super.

Tak jak pisałem, plik jest generowany przez zewnętrzną aplikację (opartą na JBOSS w Linuksie) i jest to niezależne ode mnie. Znacznik CR nie powinien się tam znajdować.

Chodziło mi o OS na którym działasz.

Przyznaję, że tu może tkwić błąd. Tak, jak pisałem wcześniej aplikacje piszę dorywczo i na własne potrzeby i dlatego być może źle zinterpretowałem to, co Lazarus robi podczas wczytywania linii. Byłem pewny, że nie dodaje znacznika CRLF, a jedynie wczytuje linię w niezmienionej postaci i przechodzi do odczytu nowej linii w pliku.

No to już wiesz.

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Tuchów
  • Postów:12171
0

Jeżeli faktycznie (jakim cudem to nie wiem...) plik wygląda tak:

Kopiuj
pierwsza linia <LF>
druga linia <LF>
trzecia <CR> linia <LF>
czwarta linia <LF>

to nie możesz wykorzystać gotowych rozwiązań jak TStrings/TStringList, bo one podczas ładowania zawartości pliku podzielą go na linie według własnego upodobania; Musisz sam wczytywać linie i określić kiedy będzie jej koniec, a kiedy nie;

Tak jak napisał Ci @-123oho - skorzystaj z plików amorficznych; Wczytuj po kolei znaki aż do napotkania znacznika LF; Po jego napotkaniu przeskanuj bufor czy nie zawiera CR i jeśli jest w niepożądanym miejscu to usuń go i podaj gotową linie dalej; No i tak do końca pliku;

W ten sposób nie ma opcji, że linie zostaną błędnie podzielone; Tylko nie pytaj w jaki sposób obsługuje się pliki amorficzne - poczytaj sam;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
pelsta
  • Rejestracja:prawie 19 lat
  • Ostatnio:15 dni
  • Postów:819
1
Kopiuj
const
  cr=#13;
  lf=#10;
  crlf=#13#10;
var
  s:string;
  f:file of Char;
  sof:Integer;
//...
//1. Wczytujemy cały plik do zmiennej typu string.
  AssignFile(f,'NazwaPliku');
  Reset(f);
  sof:=FileSize(f);
  SetLength(s,sof);
  BlockRead(f,s[1],sof);
  CloseFile(f);

//2. Wywalamy wszystkie CR z wczytanego stringa
  s:=StringReplace(s,cr,'',[rfReplaceAll]);

//3. Zamieniamy pojedyncze LF na CRLF (standard Windows)
  s:=StringReplace(s,lf,crlf,[rfReplaceAll]);

//4. Teraz możemy to załadować do jakiegoś Memo albo do StringList albo zapisać do pliku
  Memo1.Text:=s;
edytowany 1x, ostatnio: pelsta
Zobacz pozostałe 3 komentarze
pelsta
Nie traktuję tego jako gotowca. To jest przykład rozwiązania pewnego problemu, który pojawił się podczas tworzenia większego programu. Gotowiec jest wtedy, gdy dajesz gotowy cały program tym wszystkim skamlącym "studentom", którym nie chce się nic robić. Tym razem pytający pokazał, że próbował ale mu nie wychodzi. Nie rozumiem, jak można negatywnie ocenić post, który podaje poprawne rozwiązanie problemu i tym samym stymuluje pytającego do kontynuowania pracy nad programem. Piszę to jako były belfer :)
flowCRANE
To jest gotowiec, przecież Twój kod ani trochę nie przypomina jego... Dałeś mu gotowe rozwiązanie (wraz z kodem), a powinieneś podpowiedzieć co jest złego w jego algorytmie i napisać co naprawić/zmienić/zoptymalizować; W każdym razie nie dawaj kodów - zbyt dużo już ich zostało rozdane ;]
pelsta
Każdy ma swój sposób pomagania innym. Uszanujmy to i nie krytykujmy się nawzajem. Nie zmuszaj mnie do postępowania wbrew sobie bo i tak nic nie osiągniesz. Jeżeli minusowanie moich postów sprawia Ci przyjemność to proszę bardzo - nie żałuj sobie.
flowCRANE
Daj spokój, nie sprawia mi żadnej przyjemności - rzadko daję minusy (w sumie tylko za gotowce i głupkowate ospowiedzi); Chciałem tylko zaznaczyć, że dawanie kodów to rozwiązywanie problemów za pytaczy; Rozwiązałeś problem za autora wątku, nie dałeś mu pogłówkować trochę; Jeśli to jest Twój sposób na pomaganie - dobrze, uszanuję to; Masz +1 ode mnie, bo autor widocznie zapomniał Cię docenić;
pelsta
Dzięki. Autor jest pewnie niezarejestrowanym, jednorazowym userem.
0
pelsta napisał(a):
Kopiuj
const
  cr=#13;
  lf=#10;
  crlf=#13#10;
var
  s:string;
  f:file of Char;
  sof:Integer;
//...
//1. Wczytujemy cały plik do zmiennej typu string.
  AssignFile(f,'NazwaPliku');
  Reset(f);
  sof:=FileSize(f);
  SetLength(s,sof);
  BlockRead(f,s[1],sof);
  CloseFile(f);

//2. Wywalamy wszystkie CR z wczytanego stringa
  s:=StringReplace(s,cr,'',[rfReplaceAll]);

//3. Zamieniamy pojedyncze LF na CRLF (standard Windows)
  s:=StringReplace(s,lf,crlf,[rfReplaceAll]);

//4. Teraz możemy to załadować do jakiegoś Memo albo do StringList albo zapisać do pliku
  Memo1.Text:=s;

Dzięki bardzo, chyba właśnie o to mi chodziło. Jutro w pracy przetestuję to rozwiązanie. Jeżeli zadziała, to pozwoli mi to stosować jako uniwersalną procedurę przy pracy nad obróbką raportów generowanych z zewnętrznej aplikacji.
Wcześniej napisałem programik do obróbki tych raportów w Turbo Delphi i tam problem nie występował - znaczniki CR były ignorowane. Ale ostatnio postanowiłem przesiąść się na Lazarusa i stąd ten temat.
Pozdrawiam
dareck

0

Przykro mi, że @pelsta za swoje otwarte podejście i bezinteresowną pomoc naraził się na takie ataki ze strony niektórych forumowiczów (a właściwie jednego). Nie było moim celem wywoływać żadnej burzy na forum.
Tak jak napisał @pelsta, procedura, którą mi podsunął jest jedynie małą cząstką programu, która rozwiązuje problem występowania niepożądanych znaczników. Uzyskany wynik jest w dalszej części programu obrabiany i tam nie potrzebuję żadnych podpowiedzi. Nie prosiłem również o gotowe rozwiązanie, a jedynie podpowiedź. Również otrzymawszy podpowiedź od @pelsty, nie ograniczyłem się do metody - kopiuj i wklej, a przerobiłem ja na własne potrzeby. O plikach amorficznych kiedyś czytałem, ale nie miałem potrzeby z tych rozwiązań korzystać i dlatego musiałem sobie tą wiedzę odświeżyć.
Jeszcze raz dziękuję @pelscie za udzielona pomoc i mam nadzieję, że w stosunku do innych będzie miał równie życzliwe podejście, jak do mnie.
Na pewno podziękowałbym w inny sposób, jeżeli miałbym taką możliwość. Niestety nie jestem zarejestrowany, gdyż jak wcześniej pisałem, programowanie jest jedynie uzupełnieniem mojej pracy.

flowCRANE
Nie przejmuj się, po prostu ktoś niedawno zapoczątkował ruch przeciw dawaniu gotowców - rozwiązywaniu problemów za autorów wątków bez ich widocznego wkładu; Trzeba btć samodzielnym i kombinować we własnym zakresie zanim zacznie się zadawać pytania, dlatego podchodzę negatywnie do podsuwania gotowych kodów; Najważniejsza jest jednak pomoc, bo o to tutaj chodzi; Ważne, że problem został rozwiązany, ale nie można zapominać, że to nie jest nasz problem, więc pomagający nie mogą być jedynymi zainteresowanymi - przede wszystkim autor powinien dążyć do rozwiązania danego problemu;
0

Przykro mi, że @pelsta za swoje otwarte podejście i bezinteresowną pomoc naraził się na takie ataki ze strony niektórych forumowiczów (a właściwie jednego).

To, że jedna osoba tak odpowiedziała nie znaczy że inni to wspierają. Tutaj każdy się komuś naraża (tzn. większość jednej osobie i jedna osoba większości).

Nie było moim celem wywoływać żadnej burzy na forum.

Jeszcze ci daleko.

Tak jak napisał @pelsta, procedura, którą mi podsunął jest jedynie małą cząstką programu, która rozwiązuje problem występowania niepożądanych znaczników. Uzyskany wynik jest w dalszej części programu obrabiany i tam nie potrzebuję żadnych podpowiedzi.

No dobrze, tylko czy to zmienia fakt że mogłeś/powinieneś napisać to sam?

Nie prosiłem również o gotowe rozwiązanie, a jedynie podpowiedź. Również otrzymawszy podpowiedź od @pelsty, nie ograniczyłem się do metody - kopiuj i wklej, a przerobiłem ja na własne potrzeby.

Bardzo się cieszymy że mamy do czynienia z osobą która jednak pracuje i jej celem nie jest metoda kopiuj&wklej, nie mniej jednak nie wszyscy tacy są.

Jeszcze raz dziękuję @pelscie za udzielona pomoc i mam nadzieję, że w stosunku do innych będzie miał równie życzliwe podejście, jak do mnie.

Mam zgoła odmienne zdanie. Większość osób nie zasługuje na gotowca.

Nie przejmuj się, po prostu ktoś niedawno zapoczątkował ruch przeciw dawaniu gotowców - rozwiązywaniu problemów za autorów wątków bez ich widocznego wkładu; Trzeba btć samodzielnym i kombinować we własnym zakresie zanim zacznie się zadawać pytania, dlatego podchodzę negatywnie do podsuwania gotowych kodów

O to właśnie chodzi.

i; Ważne, że problem został rozwiązany, ale nie można zapominać, że to nie jest nasz problem, więc pomagający nie mogą być jedynymi zainteresowanymi - przede wszystkim autor powinien dążyć do rozwiązania danego problemu;

Sam lepiej bym tego nie ujął.

Ja uważam, że skoro autor pokazał niedziałający kod który był jego, ale jego błędem było złe podejście to najlepiej wytłumaczyć czemu jest źle i jak jest dobrze, nie przez gotowca, bo autor się mniej dowie. Tym samym również jestem przeciwko gotowcom. Natomiast tutaj nie mamy do czynienia z pytaczem-nierobem, dlatego uważam że mały gotowiec jest do przeżycia. Wiem, Furious że chcesz dobrze, ale nie bądź aż tak radykalny jak ja, bo twoje opisy rozwiązań często zajmują więcej miejsca i pracy niż gotowce, a dajesz je nierobom ;) .

Poza tym, nie widzę powodów do robienia afery z jednego gotowca... Tutaj są recydywiści, ich się trzeba czepiać :P .

flowCRANE
I tak wolę więcej napisać o sposobie na rozwiązanie danego problemu niż podać krótszego gotowca; A czy to nierób czy rób - jak posłucha to poczyta i napisze ;]

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.