View Issue Details

IDProjectCategoryView StatusLast Update
0004564JEDI VCL00 JVCL Componentspublic2008-11-18 08:31
ReporterTony_CAssigned Toobones 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionno change required 
Product VersionDaily / GIT 
Target VersionFixed in Version 
Summary0004564: Embedded quotes not parsed correctly by csvparse functions
DescriptionI am using some of the Jedi csv parsing functions and have noticed that the following functions do not handle embedded quotes as I would expect
JvStrSplit
JvAnsiStrSplitStrings

If you parse a string like this
"abc""efg"
the functions parse it out to
"abc""efg"
but I think it should return
"abc"efg"
Additional Information(This is the mod I came up with)

function JvStrSplit(const InString: string; const SplitChar, QuoteChar: Char;
  var OutStrings: array of string; MaxSplit: Integer): Integer;
var
  I, Len, SplitCounter: Integer;
  LastCh, Ch: Char;
  InQuotes: Boolean;
begin
  InQuotes := False;
  Len := Length(InString);
  for I := Low(OutStrings) to High(OutStrings) do // clear array that is passed in!
    OutStrings[I] := '';
  SplitCounter := 0; // ALWAYS ASSUME THAT ZERO IS VALID IN THE OUTGOING ARRAY.
  LastCh := #0;
  for I := 1 to Len do
  begin
    Ch := InString[I];
    if (Ch = SplitChar) and not InQuotes then
    begin
      Inc(SplitCounter);
      if SplitCounter > MaxSplit then
      begin
        Result := -1; // Error!
        Exit;
      end;
    end
    else
    begin
      if (Ch = QuoteChar) then
      begin
        InQuotes := not InQuotes;
        If (LastCh <> Ch) or (not InQuotes) then
         OutStrings[SplitCounter] := OutStrings[SplitCounter] + Ch;
      end
      else
      begin
       OutStrings[SplitCounter] := OutStrings[SplitCounter] + Ch;
      end;
    end;
    LastCh := Ch;
  end;
  Inc(SplitCounter);
  Result := SplitCounter;
end;


function JvAnsiStrSplitStrings(const InString: AnsiString; const SplitChar, QuoteChar: AnsiChar; OutStrings: TStrings): Integer;
var
  I, Len, SplitCounter: Integer;
  LastCh,Ch: AnsiChar;
  InQuotes: Boolean;
  OutString: AnsiString;
begin
  InQuotes := False;
  Len := Length(InString);
  OutStrings.Clear;
  SplitCounter := 0; // ALWAYS ASSUME THAT ZERO IS VALID IN THE OUTGOING ARRAY.
  LastCh := #0;
  for I := 1 to Len do
  begin
    Ch := InString[I];
    if (Ch = SplitChar) and not InQuotes then
    begin
      OutStrings.Add(String(OutString));
      OutString := '';
      Inc(SplitCounter);
    end
    else
    begin
     if (Ch = QuoteChar) then
     begin
       InQuotes := not InQuotes;
       If (LastCh <> Ch) or (not InQuotes) then
        OutString := OutString + Ch;
     end
     else
     begin
      OutString := OutString + Ch;
     end;
    end;
    LastCh := Ch;
  end;
  OutStrings.Add(String(OutString));
  Inc(SplitCounter);
  Result := SplitCounter;
end;
TagsNo tags attached.

Activities

obones

2008-11-18 08:31

administrator   ~0015017

As discussed in the newsgroups

Issue History

Date Modified Username Field Change
2008-11-03 22:44 Tony_C New Issue
2008-11-18 08:31 obones Note Added: 0015017
2008-11-18 08:31 obones Status new => resolved
2008-11-18 08:31 obones Resolution open => no change required
2008-11-18 08:31 obones Assigned To => obones