[fpc-pascal] CSV

Luiz Americo pascalive at bol.com.br
Mon Feb 5 00:15:20 CET 2007


Antal escreveu:
>> For example: if you want that the csv string 'aaaa;bb bb;cccc' becomes a
>> TStrings with 3 items (aaaa, bb bb and  cccc), is necessary to transform
>> 'aaaa;bb bb;cccc' into 'aaaa;"bb bb";cccc'
>> But to do this in a generic way, without knowing if determined value has
>> space than you have to parse each item of the csv, check if has space
>> and then quote. But in this case is better to add the string directly
>> through add method.
> I'm also using CSV handling in my programs, and I do it in the 
> following way, since I also have these problems:
> * I use not ";" separator, but TAB (#9) separator, which is somehow 
> the same, though it is very common to have texts containing ";" or 
> other special characters like " or blank-space, which can be messy in 
> the real ";" separated tables.
The function is delimiter agnostic: you can use any delimiter
> * I'm reading the file as 'File of char', which anyway permit a better 
> parsing, but it's a real slow solution, it takes a lot to process a 
> file of char, byte by byte.
> If useful, I can share the codes with you, but I'm not really 
> satisfied with this solution neither.
>
> Are there any other solutions available for this?
> Or how to speed up reading and processing the raw file?
Use ReadLn??. BlockRead??

The function is really simple. Look:

procedure CSVToStrings(const ACSVStr: String; AStrList: TStrings; 
Delimiter: Char = ';');
var
  pos1,pos2:Integer;
begin
  pos1:=1;
  pos2:=pos(Delimiter,ACSVStr);
  while pos1 < pos2 do
  begin
    AStrList.Add(Copy(ACSVStr,pos1,pos2-pos1));
    pos1:=pos2+1;
    pos2:=posex(Delimiter,ACSVStr,pos1);
  end;
  if pos1 < length(Trim(ACSVStr)) then
    AStrList.Add(Copy(ACSVStr,pos1,succ(length(ACSVStr)-pos1))); 
end;

Luiz



More information about the fpc-pascal mailing list