Displaying a CSV File

Program DisplayCSV reads a CSV file and uses the pos and posEx functions to format the output to the screen. We add a comma after the last field to make the processing of fields consistent. Starting from the left of the string, if a comma is found with the pos function then all the characters before the comma make up a field and all the characters to the right of the comma (if any) make up the next string to be processed in the same way.

In procedure ProcessCSVposEx, PosEx(SubString, MainString, Offset) returns the index of SubString in MainString, beginning the search at Offset. If the Offset is 1 (the default), then the function posEx is equivalent to pos. This ability to search from a character position greater than one allows us to separate the original string into fields rather than repeatedly beheading it.

For your convenience, we include a procedure that saves the test CSV file into your program folder.

program DisplayCSV;
  {$APPTYPE CONSOLE}
uses
  SysUtils, StrUtils;
const
  FILENAME = 'marks.csv';

procedure SaveCSV;
var
  CSVFile : textFile;
begin
  assignFile(CSVFile, 'marks.csv');
  rewrite(CSVFile);
  writeln(CSVFile,'Forename, Surname, Theory Mark, Practical Mark');
  writeln(CSVFile,'Jo, Wood, 55, 66');
  writeln(CSVFile,'John, Bode, 73, 58');
  writeln(CSVFile,'Kapil, Shah, 59, 58');
  closeFile(CSVFile);
end;

procedure ProcessCSV(strFileName : string);
const
  MAX_COLS = 100;
  MAX_ROWS = 10;
  SPACING = 2;
var
  CSVFile : textFile;
  CurrentString, CurrentField : string;
  CommaPosition, UsedCols, UsedRows, ColCount, RowCount, NoOfSpaces : integer;
  Table :  array [1 .. MAX_COLS, 1 .. MAX_ROWS] of string;
  ColWidths : array [1 .. MAX_ROWS] of integer;
begin
  assignFile(CSVFile, strFilename);
  reset(CSVFile);
  UsedCols := 0;
  UsedRows := 0;
  while not eof(CSVFile) do
    begin
      readln(CSVFile, CurrentString);
      CurrentString := CurrentString + ',';
      inc(UsedCols);
      UsedRows := 0;
      repeat
        CommaPosition := pos(',', CurrentString);
        if CommaPosition > 0 then
          begin
            inc(UsedRows);
            CurrentField := leftStr(CurrentString, CommaPosition - 1);
            CurrentString := rightStr(CurrentString,
                             length(CurrentString) - CommaPosition);
            Table[UsedCols, UsedRows] := CurrentField;
          end;
      until CommaPosition = 0;
    end;
  closeFile(CSVFile);
  //Find max field length for each column
  for RowCount := 1 to UsedRows do
    begin
      colWidths[RowCount] := Length(Table[1, RowCount]);
      for ColCount := 2 to UsedCols do
        begin
          if length(Table[ColCount, RowCount]) >  colWidths[RowCount] then
            begin
              colWidths[RowCount] := length(Table[ColCount, RowCount]);
            end;
        end;
    end;
  //Output the data, right justified
  for ColCount := 1 to UsedCols do
    begin
      for RowCount := 1 to UsedRows do
        begin
          write(Table[ColCount, RowCount] : colWidths[RowCount] + SPACING);
        end;
        writeln;
    end;
  writeln;
  //Output the data, left justified
  for ColCount := 1 to UsedCols do
    begin
      for RowCount := 1 to UsedRows do
        begin
          CurrentField := Table[ColCount, RowCount];
          NoOfSpaces := colWidths[RowCount] + SPACING - length(CurrentField);
          write(CurrentField,  stringOfChar(' ', NoOfSpaces));
        end;
        writeln;
    end;
  writeln;
end;

procedure ProcessCSVposEx (strFileName : string);
var
  CSVFile : textFile;
  CurrentString, CurrentField : string;
  CommaPosition, StartPos : integer;
begin
  assignFile(CSVFile, strFilename);
  reset(CSVFile);
  while not eof(CSVFile) do
    begin
      readln(CSVFile, CurrentString);
      CurrentString := CurrentString + ',';
      StartPos:=1;
      repeat
        CommaPosition := posEx(',', CurrentString, StartPos);
        CurrentField := MidStr(CurrentString, StartPos,
                               CommaPosition - StartPos);
        StartPos := CommaPosition + 1;
        write(CurrentField, ' ');
      until (CommaPosition = 0);
      writeln;
    end;
  closeFile(CSVFile);
end;

begin
  SaveCSV;
  ProcessCSV(FILENAME);
  ProcessCSVposEx(FILENAME);
  readln;
end.  

The program produced the following output from our test file.

Output from program DisplayCSV

Output from program DisplayCSV

Programming - a skill for life!

Introduction to the string manipulation of text files