[Delphi] readln geeft vreemde characters terug

Pagina: 1
Acties:
  • 128 views sinds 30-01-2008
  • Reageer

  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Ik krijg bij het uitlezen van sommige *.reg files opmaak character terug.

eerste regel:
Windows Registry Editor Version 5.00

wordt omgezet naar:
'ÿþW'#0'i'#0'n'#0'd'#0'o'#0'w'#0's'#0' '#0'R'#0'e'#0'g'#0'i'#0's'#0't'#0'r'#0'y'#0' '#0'E'#0'd'#0'i'#0't'#0'o'#0'r'#0' '#0'V'#0'e'#0'r'#0's'#0'i'#0'o'#0'n'#0' '#0'5'#0'.'#0'0'#0'0'#0

Code:
procedure TForm1.Convert();
var
sFilename : Textfile;
sLine : AnsiString;

begin
sFullList := TStringList.Create;
AssignFile(SFilename, Regfilename);
Reset(SFilename);
while not EOF(SFilename) do begin
Readln(SFilename, sLine);
sFullList.add(sLine);
end;
CloseFile(SFilename);
end;

Als ik een tekst file maak en de tekst van de *.reg daar in kopieer ( via notepad ) dan kan de tekst wel correct ingelezen worden. Wat voor kenmerk kan er nu een een *.reg file zitten waardoor hij anders ingelezen wordt.

Ik heb via google ook al lopen zoeken,.. maar geen resultaat.

[ Voor 27% gewijzigd door Devour op 18-06-2004 12:57 ]

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23-05 23:27

Tomatoman

Fulltime prutser

Zo te zien is de tekst in unicode opgemaakt. Unicode tekst kun je niet zomaar uitlezen met een TStringList. Je zult eerst de unicode tekst moeten uitlezen en omzetten naar ANSI tekst.

Een goede grap mag vrienden kosten.


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Dat kan ik begrijpen,... maar weet je ook hoe ik dat om kan zetten?
Wederom geeft google niet een oplossing.

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Dan heb je niet gezocht denk ik want hier unicode+to+ansi+delphi is het met de tweede link al bingo :?

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23-05 23:27

Tomatoman

Fulltime prutser

Delphi:
1
WideCharToString
:Z

Een goede grap mag vrienden kosten.


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Ik heb nu meerder oplossingen geprobeerd, maar het omzetten wil echt niet lukken. De methode van WideString naar AnsiString/String omzetten werkt niet.

Hoe kan ik zeker weten dat het unicode is en niet Multybyte code?

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23-05 23:27

Tomatoman

Fulltime prutser

Wat bedoel je precies met 'werkt niet'? We kunnen moeilijk aangeven wat je verkeerd doet als je geen betere uitleg geeft.

Een goede grap mag vrienden kosten.


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Mijn excuss dat ik niet duidelijker was.

Wat ik nu heb geprobeerd werkt enigzins, maar nog niet helemaal.
code:
1
2
Readln(SFilename, sLine);
WideCharToString(pWideChar(sLine));


uitkomst:
?Windows Registry Editor Version 5.00??D?Á?

[ Voor 5% gewijzigd door Devour op 18-06-2004 13:55 ]

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:55

Creepy

Tactical Espionage Splatterer

en sline is nog steeds een AnsiString??

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TForm1.Convert();
var
  sFilename : Textfile;
  sLine : AnsiString;

begin

  //inlezen van de file

  AssignFile(SFilename, Regfilename);
  Reset(SFilename);
  while not EOF(SFilename) do begin
    Readln(SFilename, sLine);
    sLine := WideCharToString(pWideChar(sLine));
    sFullList.add(sLine);
  end;
  CloseFile(SFilename);

end;


Ja, dus ;)

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:55

Creepy

Tactical Espionage Splatterer

Die ;) geeft al aan dat je m'n hint niet doorhebt. Misschien was ik te subtiel :)

Je had er nog niet bij nagedacht dat je nu dus die data eerst in een ansistring leest, die cast naar een pWideChar en dan pas door de WideCharToString functie voert?

Jou zou eens kunnen proberen om van sline ook een pWideChar of een WideString te maken zodat er geen automatische omzetting meer plaats vindt, en je die cast ook niet meer nodig heb.

[ Voor 30% gewijzigd door Creepy op 18-06-2004 14:03 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Het probleem is dat de Readln niet een andere type dan String wil hebben.
Ik heb verschillende casts geprobeer, maar een beter resultaat dan hierboven lukt niet :(

Ik vindt het ook zo vreemd dat een *.reg file unicode is ,... zou het niet iets anders kunnen zijn?

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

Devour schreef op 18 juni 2004 @ 14:34:
Ik vindt het ook zo vreemd dat een *.reg file unicode is ,... zou het niet iets anders kunnen zijn?
offtopic:
Waarom zou dat vreemd zijn? Er zijn ook andere versies van Windows dan de Nederlandse en Engelse. Hoe wou jij Chinese tekens opslaan in een bestand waar alleen een Westerse karakterset in mag?

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 23-05 23:27

Tomatoman

Fulltime prutser

Je zult de hele tekst als een geheel moeten uitlezen, dan van unicode naar ANSI converteren en daarna pas kun je de tekst in een TStringList bewerken. Ik betwijfel of dat lukt met een Textfile. Eventueel moet je het bestand inlezen als een TFileStream of een memory-mapped file.

Een goede grap mag vrienden kosten.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Devour schreef op 18 juni 2004 @ 13:41:
Ik heb nu meerder oplossingen geprobeerd, maar het omzetten wil echt niet lukken. De methode van WideString naar AnsiString/String omzetten werkt niet.

Hoe kan ik zeker weten dat het unicode is en niet Multybyte code?
De eerste 2 characters zijn 0xFFFE, dat is de identifier voor een Unicode-textfile.

Professionele website nodig?


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Ik heb besloten om het over een andere boeg te gooien en dit werkt beter:

code:
1
2
3
4
5
6
7
8
9
    iRegFile := TIniFile.Create(RegFilename); //inlezen van de file
    iRegFile.ReadSections(sKey); //inlezen van de Keys

    //converteren
    sOutput.Add('item: Edit Registry');
    For i:=0 to sKey.Count-1 do //doorlopen van de keys
      begin
        iKeyRoot:=GiveRoot(sKey[i]); //bepalen van de Hkey
        MyReadSectionValues(sKey[i],sValue); //inlezen van Value

Het component TIniFile converteerd de file direct goed. :)
Ook hier zitten een paar nadelen aan, want een key zonder value wordt overgeslagen. ( naam='' wordt overgeslagen)

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

tomatoman schreef op 18 juni 2004 @ 15:03:
Je zult de hele tekst als een geheel moeten uitlezen, dan van unicode naar ANSI converteren en daarna pas kun je de tekst in een TStringList bewerken. Ik betwijfel of dat lukt met een Textfile. Eventueel moet je het bestand inlezen als een TFileStream of een memory-mapped file.
Correct is:
• hele bestand inlezen in buffer
• eerste 2 bytes testen op 0xFFFE
• zo nee, hele string hardpointered in AnsiString frotten
• zo ja, eerste 2 bytes overslaan en de rest hard in WideString frotten

De conversie hoef je zelf niet te doen, AnsiString en WideString hebben onderling voldoende conversiemogelijkheden. Vergeet niet dat je data weggooit als je van een WideString naar een AnsiString gaat (moet om die reden ook expliciet gebeuren middels constructor).

Professionele website nodig?


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Wat je schrijft klinkt heel geloofwaardig, maar of het in de praktijk ook werkt is een heel ander verhaal. Ik heb nu heel wat geprobeerd, met verschillende typecasts en verschillende convertfuncties, maar niet werkt helemaal lekker.

Ik vermoed dat een deel ANSI code is en een deel Unicode.
Dit kan ik helaas niet helemaal theoretischonderbouwen, maar in de praktijk heb ik gezien dat delen wel te converteren zijn, maar dat andere delen dan niet meer kloppen. Ik heb nu dus een andere manier gevonden die beter werkt. ( via TiniFile ) :)

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.


  • __fred__
  • Registratie: November 2001
  • Laatst online: 22:44
Devour schreef op 18 juni 2004 @ 15:41:
Wat je schrijft klinkt heel geloofwaardig, maar of het in de praktijk ook werkt is een heel ander verhaal. Ik heb nu heel wat geprobeerd, met verschillende typecasts en verschillende convertfuncties, maar niet werkt helemaal lekker.

Ik vermoed dat een deel ANSI code is en een deel Unicode.
Dit kan ik helaas niet helemaal theoretischonderbouwen, maar in de praktijk heb ik gezien dat delen wel te converteren zijn, maar dat andere delen dan niet meer kloppen. Ik heb nu dus een andere manier gevonden die beter werkt. ( via TiniFile ) :)
Een file is natuurlijk altijd helemaal unicode of helemaal niet. Als je nou de volgende keer een unicode file in wilt lezen en converteren naar ansi dan werkt het volgende:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var
  Stream : TFileStream;
  Output : String;
  Identifier : Array[0..1] of byte;
  Buffer : Array[0..1023] of Byte;
  Count : Integer;
begin
  Stream := TFileStream.Create('C:\test.reg', fmOpenRead);
  Stream.Read(Identifier,2);
  if (Identifier[0] = $FF) and (Identifier[1] = $FE) then
  begin
  Count := Stream.Read(Buffer,1024);
  while Count <> 0 do
    begin
      Output := Output + WideCharLenToString(@Buffer,Count div 2);
      Count := Stream.Read(Buffer,1024);
    end;
  end;
  FreeAndNil(Stream);


Daarna kun je Output gebruiken als gewone string met de inhoud van de gehele file.

[ Voor 10% gewijzigd door __fred__ op 18-06-2004 17:04 ]


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Er is ook een TTntFileStream die unicode/widestrings gewoon meteen goed inleest. Dit TnT pakage bevat meer unicode/windestrings controls en classes die je misschien zou kunnen gebruiken.

We adore chaos because we like to restore order - M.C. Escher


  • Paul
  • Registratie: September 2000
  • Laatst online: 24-05 11:37
Devour schreef op 18 juni 2004 @ 12:57:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TForm1.Convert();
var
  sFilename : Textfile;
  sLine : AnsiString;

begin
  sFullList := TStringList.Create;
  AssignFile(SFilename, Regfilename);
  Reset(SFilename);
  while not EOF(SFilename) do begin
    Readln(SFilename, sLine);
    sFullList.add(sLine);
  end;
  CloseFile(SFilename);
end;
Prachtige constructie, maar is sFullList.LoadFromFile(Regfilename) niet een stuk makkelijker? :P

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Devour
  • Registratie: Februari 2000
  • Laatst online: 15-05 09:44

Devour

Inspirator

Topicstarter
Bedankt mensen voor de tips :)

Ik zal voor optimalisatie doeleinden nog een aantal van jullie oplossing uitwerken.
Ik gebruik nu de Tinifile classe van Borland en dat werkt wel, maar een reg file is hier en daar anders dan een inifile. ( bv: lange keys worden afgebroken door een '/'. De Tinifile classe kan dan niet de volgende regel opvragen. Dus heb ik de Tinifile class op een aantal punten aangepast)

Nogmaals bedankt :)

[ Voor 5% gewijzigd door Devour op 28-06-2004 09:27 ]

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.

Pagina: 1