Skip to main content
Code Review

Return to Revisions

2 of 2
edited tags; edited title
200_success
  • 145.6k
  • 22
  • 190
  • 479

Converting fixed-width text file to CSV in C

I'm trying to get reacquainted with C after years of higher-level languages.

I wrote a small fixed-width to CSV converter. It works (for ASCII at least) and it's quite fast, but I wonder if I missed anything or if it can be made even faster.

I'm reading the file line by line and process the desired columns (some can be skipped), placing them into an output 8K buffer. I'm using one function to do the substring, appending and trimming trailing space (just the space, in this case I don't want to bother testing for other whitespace characters).

#include <ctype.h>
// number of columns to process
#define COLS 3
#define LINE_SIZE 256
#define BUFFER_SIZE 8192
#define INFILE "in.txt"
#define OUTFILE "out.csv"
size_t RANGES[COLS][2] = {{0, 6}, {6, 20}, {29, 3}};
/*
 * Copy from source to destination, up to len chars, trimming trailing spaces
 * Returns number of chars actually copied
 */
int trimcpy(char *destination, char *source, size_t len) {
 // trim spaces from the end - we only care about the space char
 while (len>0 && source[len-1]==' ')
 len--;
 int i = 0;
 while (i<len && *source != '0円') {
 *destination++ = *source++;
 i++;
 }
 *destination = '0円';
 return i;
}
int main(void) {
 FILE *rfp;
 FILE *wfp;
 char line[LINE_SIZE];
 char out[BUFFER_SIZE];
 rfp = fopen(INFILE, "r");
 if (rfp == NULL)
 exit(EXIT_FAILURE);
 wfp = fopen(OUTFILE, "w");
 if (wfp == NULL)
 exit(EXIT_FAILURE);
 int p = 0;
 // fgets is 4x faster than getline!
 while (fgets(line, LINE_SIZE, rfp) != NULL) {
 // write buffer if almost full (largest column is 20 chars)
 if (p > BUFFER_SIZE - 20) {
 fputs(out, wfp);
 p = 0;
 }
 // go through the columns
 for (int i=0; i<COLS; i++) {
 p += trimcpy(out+p, line+RANGES[i][0], RANGES[i][1]);
 p += trimcpy(out+p, i<COLS-1 ? "," : "\n", 1);
 }
 }
 // write any remaining data in buffer
 fputs(out, wfp);
 fclose(rfp);
 fclose(wfp);
 exit(EXIT_SUCCESS);
}
lang-c

AltStyle によって変換されたページ (->オリジナル) /