22. juni 2004 - 22:27Der er
22 kommentarer og 1 løsning
stringreplace ' med *
Hejsa
jeg har en tekststreng som indholder "volapyk" dvs. et array[0..1] of kunderecord som er lagt direkte ned i en fil.
Denne tekststreng indholder et hav af ' tegn og det giver problemer når jeg prøver at gemme denne tekststreng i en mysql database.. fordi ' er et tegn som bruges til at adskille variabler med.
derfor har jeg tænkt mig at erstatte alle ' med * med functionen "stringreplace" som jo er en delphi funktion.
Men DELPHI brokker sig over en unterminated string.. og det er jo klart fordi den antager at ' er sat fordi jeg vil adskille en tekststreng... men det er jo ikke min hensigt.
Anyway.. jeg har prøvet med: tempstring := stringreplace(tempstring, '''', '*', [rfReplaceAll]); ... men så bliver ' ikke erstattet med *
Jeg kan ikke helt gennemskue hvad pokker jeg skal gøre for at løse problemet.
Hvad om man bruger en af funktionerne QuotedStr() eller AnsiQuotedStr(). De pløjer strengen igennem og alle steder med enkelt' bliver dobbelt - endelig indkapsles strengen med et par ''er.
procedure TForm1.ButtonGemClick(Sender: TObject); var x: integer; gridarray: Tgridarray; MapFile: file of Tgridarray; begin for x := 0 to 10 do begin gridarray[x].indhold := inttostr(x); gridarray[x].navn := 'TTextualColumn'; gridarray[x].art := 'TTextualColumn'; gridarray[x].tom := 'false'; end;
function hentgrid_frafil_somstring: string; var myFile: file; ch: char; tempstring: string; i: integer; begin AssignFile(myFile, 'hejsa.txt'); tempstring := ''; FileMode := fmOpenRead; Reset(myFile, 1); while not Eof(myFile) do begin BlockRead(myFile, ch, 1); tempstring := tempstring + ch; end; CloseFile(myFile); result := tempstring; end;
Nu er det så at jeg gerne vil have tempstring til at være en string hvor ' er lavet om til * ... men det lader ikke til at virke... når jeg læser et tegn afgangen henter proceduren stadig flere tegn igennem f.eks. '3' skulle der ikke kun komme ét tegn tilbage som f.eks. ' eller 3 ?
Når jeg kører: tempstring := stringreplace(tempstring, '''', '*', [rfReplaceAll]); som virker på andre strings så sker der virkelig ingen verdens ting.. meget skørt..!
Lad os antage at der er forsøgt fyldt 'Hej's''d''s''s''s's's's'!' ind i TempString. Det er min antagelse at Delphi er ret ligeglad med det og stopper efter 'Hej'. Har du prøvet at skrive TempString ud i en MessageBox eller tage længden på den?
Prøv at sætte en QuotedStr rundt om TempString og se hvad der sker. Det skulle ikke undre mig om den så gled lige ind i MySql.
nico.. ja det burde virke - men det gør det ikke.!?!?
hrc.. længden på min string er 3454. jeg har faktisk prøvet det der med quotedstr.. og det virkede heller ikke.. jeg fatter det simpelthen ikke.!
Af en eller anden grund lader det til at min tempstring ikke bliver gennemløbet korrekt af nogen af de nævnte procedurer og det er jo skørt.! Men faktum er at når jeg gemmer mit array til en fil og derefter samler filens tegn op enkeltvis og sætter dem sammen til en streng - så sker der noget som ikke skal ske.
Jeg har set at selv om min procedure burde samle ét tegn op fra filen - så kan den finde på at samle #4 op.. efter min logik er det to tegn eller`? Og her er det min mistanke bliver - nemlig at '3' kan blive betragtet som ét tegn og ikke tre. Men det virker meget mærkeligt.
For at få det til at køre bliver jeg vel nød til at gennemløbe mit array og selv lave min tempstring "manuelt" f.eks. med værdier adskilt med ; eller sådan noget.. men jeg synes bare det andet burde virke.
det virker til at der er forskel på hvad jeg kan vise ved en showmessage og en "halt-step-by-step" (jeg ved ikke hvad det hedder men det er den funktion hvor man sætter en rød prik ud for den linie som delphi skal stoppe ved) kørsel i delphi. Hvis jeg showmessage'er tempstring[3] altså det 3. tegn i strengen.. så bliver der vist et helt andet tegn end ved denne der før nævnte "halt-step-by-step-delphi-ting".
jeg lukker dette spørgsmål og deler point ud til alle som har bidraget med viden.. så hvis alle i spørgsmålet (som ønsker points) lige ville komme med et "svar".. så deler jeg points ud i morgen.
.. jeg ønsker alle tak med Jeres bidrag.. men der må være en eller anden bug i delphi lige på dette lige felt. Hvis jeg en dag finder ud af en løsning eller hvad problemet var - poster jeg det.
Min løsning blev at gennemløbe arrayet inden det blev lagt en i en fil og lave min egen string med værdier adskildt med et ; Håbløs workaround - men det virker i det mindste.
Jeg ved nu ikke om din løsning er så dum endda. Jeg startede egentlig denne kommentar for at spørge hvorfor du ikke bare læste TGridArray ind igen, sådan som den var skrevet. For mig at se, er det hvad du har brug for.
procedure TForm1.HentGridFraMapFil(var aGrid : TGridArray); var i : integer; MapFileStream : TFileStream; begin i := 0; // Du har en grid på 11 elementer - er det en fejl? MapFileStream := TFileStream.Create('hejsa.dat',fmOpenRead); try for i := low(aGrid) to high(aGrid) do MapFileStream.ReadBuffer(aGrid[i],sizeof(TDelTur)); finally MapFileStream.Free; end; // try end;
procedure TForm1.SkrivGridTilMapFil(aGrid : TGridArray); var i : integer; MapFileStream : TFileStream; begin MapFileStream := TFileStream.Create('Hejse.dat',fmCreate); try for i := low(aGrid) to high(aGrid) do begin with aGrid[i] do begin Indhold := IntToStr(i); Navn := 'TTextualColumn'; Art := 'TTextualColumn'; // Burde være en enum type! Tom := 'false'; // Hvorfor ikke bare lave den til en boolean? end; MapFileStream.WriteBuffer(aGrid[i],sizeof(TDelTur)); end; // for finally MapFileStream.Free; end; // try end;
Beklager at jeg ikke har haft tid til at kigge dit spørgsmål igennem - håber jeg har ramt noget rigtigt denne gang - sender i alt fald et svar.
Bemærk, at ovenstående ikke er testet, men det håber jeg at få tid til lidt senere. Jeg bruger i øvrigt TFileStreams i stedet for "file of TEtEllerAndet" og blockread - synes det sidste er noget antikveret. Egentlig burde man nedarve TFileStream til en variant der håndterede TDelTur direkte (en nem og pæn løsning)
const FileNameConst = 'Hejsa.dat'; // Lav konstant i stedet for at skrive 2 steder i koden
type TDelTurTypes = (dttTextualColumn); // Bare tilføj flere om de dukker op
(* TDelTur = record // Din record Indhold : string[100]; Art : string[100]; Navn : string[100]; Tom : string[10]; end; *)
TDelTur = record // Sparer ca. 108 tegn pr. record ved at lave denne version Indhold : string[100]; Art : TDelTurTypes; Navn : string[100]; Tom : boolean; end;
procedure TfrmMain.Read(const aFileName : string); var i : integer; MapFileStream : TFileStream; begin MapFileStream := TFileStream.Create(aFileName,fmOpenRead); try for i := low(fGrid) to high(fGrid) do MapFileStream.ReadBuffer(fGrid[i],sizeof(TDelTur)); finally MapFileStream.Free; end; // try end;
procedure TfrmMain.Save(const aFileName : string); var i : integer; MapFileStream : TFileStream; begin MapFileStream := TFileStream.Create(aFileName,fmCreate); try for i := low(fGrid) to high(fGrid) do MapFileStream.WriteBuffer(fGrid[i],sizeof(TDelTur)); finally MapFileStream.Free; end; // try end;
procedure TfrmMain.btnGenerateClick(Sender: TObject); var i : integer; begin for i := low(fGrid) to high(fGrid) do with fGrid[i] do begin Indhold := IntToStr(i); Navn := 'TTextualColumn'; Art := dttTextualColumn; // 'TTextualColumn'; Tom := false; end; end;
procedure TfrmMain.btnSaveClick(Sender: TObject); begin Save(FileNameConst); end;
procedure TfrmMain.btnReadClick(Sender: TObject); begin Read(FileNameConst); end;
end.
Hvis du vil have en demo af en nedarvet TFileStream, så kan du sige til.
jamen dog.. hrc det ser interessant ud.. men jeg kan ikke helt se hvordan det løser mit problem nemlig at jeg have mit array lavet om til en string som jeg kan lagre i en database. Derefter skal jeg kunne lave den om igen til et array og gemme det i filen igen.
.. det er sikkert mig som ikke forstår hvad du mener. Men det som jeg ser i dit eksempel er en lækker facon at gemme et array ned i en fil og hente den tilbage igen. Og jeg hilser dit oplæg velkommen fordi jeg bestemt kan lære en masse af det.. men det løser bare ikke rigtig mit problem.... der må "mangle" to knapper.. nemlig: "lav array om til string" og "lav string om til array".
Jeg tror nok at jeg har en forståelsesblokade fordi jeg synes det er underligt, at du vil gemme hele recorden i et strengfelt.
Skulle jeg gemme recorden i en database, ville jeg gøre det i et blob-felt og så have søgetekst placeret i et specifikt søgefelt (Desuden ville jeg bruge nul-terminerede strenge så der ikke var så meget pladsspild).
Helt ideelt ville jeg nok lave en tabel der havde samme felter som recorden. Det er noget skod det du er på vej ud i - synes jeg altså.
Jeg har heller ikke helt forstået konceptet, men kan da pege på et par ting:
Når du gemme dit array på den måde og ønsker at læse det som en streng er der en bunke, der går galt.
1. Strengene gemmes på disken som en byte indeholdende længden efterfulgt af indholdet. Derfor vil du støde ind i "underlige" tegn når du læser fra filen. #3 er IKKE to tegn, men en byte med værdien 3 (sikkert en længde).
2. Når du ikke benytter packed record word eller dword aligner delphi felterne. Derfor vil du finde enten nuller eller tilfældige værdier mellem strengende i filen (prøv at åbne den med en hex editor). Og så vil din temp string indeholde nuller på forskellige steder - og så er der intet der vil virke.
>> hrc : sorry, din mail blev "glemt" i en mailserver ændring - svarer dig asap
..jeg prøver at hjælpe en kammerat med et projekt han har.. problemet er en ringe databasestruktur samt kun at have én tuppel til rådighed til dette array.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.