CSV spreadsheet files are suitable for storing tabular data in a relatively portable way.

The CSV format is flexible but somewhat ill-defined.

For present purposes, authors may assume that the data fields contain no commas, backslashes, or quotation marks.



Task

Read a CSV file, change some values and save the changes back to a file.

For this task we will use the following CSV file:

C1,C2,C3,C4,C5
1,5,9,13,17
2,6,10,14,18
3,7,11,15,19
4,8,12,16,20

Suggestions


 Show how to add a column, headed 'SUM', of the sums of the rows.
 If possible, illustrate the use of built-in or standard functions, methods, or libraries, that handle generic CSV files.



void
read_csv(list t, text path)
{
    file f;
    list l;
 
    f_affix(f, path);
    while (f_news(f, l, 0, 0, ",") ^ -1) {
        l_append(t, l);
    }
}
 
list
sum_columns(list t)
{
    list c, l;
    integer i;
 
    l_append(c, "SUM");
    for (i, l in t) {
        if (i) {
            integer j, sum;
            text s;
 
            sum = 0;
            for (j, s in l) {
                sum += atoi(s);
            }
 
            l_append(c, sum);
        }
    }
 
    return c;
}
 
void
add_column(list t, list c)
{
    integer i;
    list l;
 
    for (i, l in t) {
        l_append(l, c[i]);
    }
}
 
void
write_csv(list t, text path)
{
    integer i;
    file f;
    list l;
 
    f_create(f, path, 00644);
    for (i, l in t) {
        f_(f, l[0]);
        l_ocall(l, f_, 2, 1, -1, f, ",");
        f_newline(f);
    }
}
 
integer
main(void)
{
    list t;
 
    read_csv(t, "tmp/CSV_data_manipulation.csv");
    add_column(t, sum_columns(t));
    write_csv(t, "tmp/CSV_data_manipulated.csv");
 
    return 0;
}