Die ganze Diskussion ist hinfällig, da es keine einheitliche
CSV Format gibt.
Zitat von
Wikipedia:
Ein allgemeiner Standard für das Dateiformat
CSV existiert nicht, jedoch wird es im
RFC 4180 grundlegend beschrieben
Diese Beschreibung ist aber nur
eine mögliche. Nach der
Ansi Norm sind *.csv Dateien in unserem Sprachraum mit einem Semikolon getrennt.
Excel verwendet z.B. diese
Ansi Norm. Mach mal einen Doppelklick auf eine mit Komma getrennte
csv Datei.
Es macht also keinen Sinn hier über Implementierungsdetails streiten.
Folgendes Beispiel ist auch NICHT
rfc konform:
Code:
MaBuSE,"Hauptstraße 5",12345,Musterstadt
(Das "ß" ist nicht erlaubt.)
Das Zeilenwechsel Problem ist ja auch kein CSV spezifisches Problem. Das gibt es grundsätzlich beim Austausch von Textdateien zwischen PC <-> Unix <-> alte Mac.
Ein Zeilenwechsel kann sein #13#10, #10 oder auch #13
Letzteres war früher bei Macs, ist aber mittlerweile unüblich.
TStringList kann auf PC vernünftig nur mit #13#10 umgehen. Je nachdem wie man die Daten zuweist, wird es auch nach #13#10 umgewandelt oder nicht.
Das ist aber auch schon ewig so.
Ich habe das nach dem Laden/Zuweisen immer mit einem
sl.Text := sl.Text;
gelöst. Damit werden alle #13 und #10 zu #13#10 umgewandelt.
Hier zum Testen: (Leeres Form mit einem TButton und 5 TMemo)
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
sl: TStringList;
begin
sl := TStringList.Create;
sl.Add('Aa,Bb');
sl.Add('"A'#13#10'a",Bb');
sl.Add('"A'#10'a",Bb');
sl.Add('"A'#13'a",Bb');
Memo1.Lines.Text := sl.Text; // mit Umwandlung von #13 und #10 nach #13#10
Memo2.Lines.Add(sl.Text); // ohne Umwandlung
Memo3.Lines.Text := s2hex(Memo1.Lines.Text);
Memo4.Lines.Text := s2hex(Memo2.Lines.Text);
Memo5.Lines.Text := s2Hex(sl.Text);
end;
function TForm1.s2hex(s: string): string;
var
i: Integer;
begin
for i := 1 to length(s) do
begin
Result := Result + IntToHex(Ord(s[i]),2) + #32;
end;
end;
-> so sieht es dann aus:
Code:
Memo1:
Aa,Bb
"A
a",Bb
"A
a",Bb
"A
a",Bb
Memo2:
Aa,Bb
"A
a",Bb
"Aa",Bb
"Aa",Bb
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0A 61 22 2C 42 62 0D 0A 22 41 0D 61 22 2C 42 62 0D 0A // sl.Text
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A // sl.Text nach Text := Text
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A // Memo1.Lines.Text
41 61 2C 42 62 0D 0A 22 41 0D 0A 61 22 2C 42 62 0D 0A 22 41 0A 61 22 2C 42 62 0D 0A 22 41 0D 61 22 2C 42 62 0D 0A 0D 0A // Memo2.Lines.Text mit zusätzlichem #13#10 am Ende (durch das Add)