there was a problem with correct reading from a CSV file, it seems to be reading normally, but if the columns in which there is a symbol in the text itself; and then the columns begin to read incorrectly, can anyone encountered a similar problem? Here is my code for reading:

procedure TForm1.N2Click(Sender: TObject); var f: TextFile; s1, s2,FileName: string; i, j: integer; separator:char; begin if OpenDialog1.Execute then begin edit1.Text:=OpenDialog1.FileName; FileName:=OpenDialog1.FileName; separator:=';'; i := 0; AssignFile (f, FileName); Reset(f); while not eof(f) do begin readln (f, s1); i := i + 1; j := 0; while pos(separator, s1)<>0 do begin s2 := copy(s1,1,pos(separator, s1)-1); j := j + 1; delete (s1, 1, pos(separator, S1)); StringGrid1.Cells[j-1, i-1] := s2; end; if pos (separator, s1)=0 then begin j := j + 1; StringGrid1.Cells[j-1, i-1] := s1; end; StringGrid1.ColCount := j; StringGRid1.RowCount := i+1; end; CloseFile(f); end; end; end. 

csv is formed correctly, in quotes ... but there was still a problem, there is a line feed in some cells ... it would also need to be considered ...

solved the problem in a different way, I basically just need to process the array of data from the file without displaying it, the snag was in reading the data, so I read from this file through EkselPP

  ExlApp := CreateOleObject('Excel.Application'); ExlApp.Visible := false; ExlApp.Workbooks.Open(XLSFile); 

I just read the data into the array and continue to work with them

  • Is csv itself properly formed? Is the text that contains the delimiter surrounded by quotes? - Vladimir Klykov
  • Yes, csv is formed correctly, in quotes ... but there was still a problem, there is a line feed in some cells ... it would also need to be considered ... - arashvg

1 answer 1

Try this:

 Var inFile : TMemoryStream; StrRd : Boolean; CurStr : String; Buf : AnsiChar; Col,Row: Integer; begin inFile := TMemoryStream.Create; inFile.LoadFromFile('C:/price.csv'); inFile.Position:=0; StrRd :=False; Col :=0; Row :=0; while inFile.Position<>inFile.Size do Begin inFile.Read(Buf,SizeOf(Buf)); if(Buf='"') then StrRd:=not StrRd; if((Buf=';') and (StrRd=False)) then Begin StringGrid1.Cells[Col,Row]:=CurStr; CurStr:=''; Col:=Col+1; End else if((Buf=#13) and (not StrRd)) then Begin Row:=Row+1; StringGrid1.Cells[Col,Row]:=CurStr; StringGrid1.RowCount:=StringGrid1.RowCount+1; CurStr:=''; Col:=0; End else CurStr:=CurStr+Buf; End; End; 

Immediately I warn you - the optimization is exactly zero, but it works like smart (relatively). Normally digests line breaks and quotes inside text framed in quotes.

ps. the possibility of quotes inside strings is not taken into account, if any (correctly escaped) - nothing bad will happen, just in the output array - they will not be.

  • To count quotes inside quotes, you need a state machine with three states, and you only have two. - German Borisov
  • @HermanBorisov, I know, just warned the author of the issue about this minor flaw, I remembered that the quote was screened just after writing the code. - Vladimir Klykov
  • one
    I am more for passing by than for you. - German Borisov