Skip to content

Instantly share code, notes, and snippets.

@dmoulding
Created December 2, 2009 06:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dmoulding/246988 to your computer and use it in GitHub Desktop.
Save dmoulding/246988 to your computer and use it in GitHub Desktop.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char * append (char *field, size_t *size, size_t *len, char c);
static size_t get_field (char **field, size_t *size, FILE *file);
static char const * strip_field (char *field, size_t len);
static bool end_of_file = false;
static bool end_of_line;
int
main (int argc, char *argv [])
{
char *field = NULL;
FILE *file;
char const *filename;
size_t len;
size_t size = 0;
char const *stripped;
if (2 != argc) {
printf("Exactly one filename must be specified\n");
return EXIT_FAILURE;
}
filename = argv[1];
file = fopen(filename, "r");
if (NULL == file) {
printf("%s: file not found\n", filename);
return EXIT_FAILURE;
}
NEW_LINE:
len = get_field(&field, &size, file);
stripped = strip_field(field, len);
if (strcmp("", stripped)) {
printf("%s", stripped);
if (end_of_file) {
goto EXIT;
}
} else {
if (end_of_file) {
goto EXIT;
}
printf("null");
}
while (!end_of_line) {
len = get_field(&field, &size, file);
printf("|%s", strip_field(field, len));
if (end_of_file) {
goto EXIT;
}
}
printf("\n");
goto NEW_LINE;
EXIT:
free(field);
fclose(file);
return EXIT_SUCCESS;
}
char *
append (char *field, size_t *size, size_t *len, char c)
{
if (*size <= (*len + 1)) {
field = (char *)realloc(field, *size + 64);
*size += 64;
}
field[(*len)++] = c;
return field;
}
size_t
get_field (char **field, size_t *size, FILE *file)
{
int c;
size_t len = 0;
end_of_line = false;
c = fgetc(file);
while ('|' != c) {
if ('\n' == c) {
end_of_line = true;
goto EXIT;
}
if (EOF == c) {
end_of_file = true;
goto EXIT;
}
*field = append(*field, size, &len, c);
c = fgetc(file);
}
EXIT:
(*field)[len] = '\0';
return len;
}
char const *
strip_field (char *field, size_t len)
{
size_t b;
size_t e;
if (0 == len) {
return field;
}
for (b = 0; b < len; ++b) {
if ((' ' != field[b]) && ('\t' != field[b])) {
break;
}
}
for (e = len - 1; e > b; --e) {
if ((' ' != field[e]) && ('\t' != field[e])) {
break;
}
}
if (e == b) {
field[b] = '\0';
} else {
field[e + 1] = '\0';
}
return field + b;
}
// Local Variables:
// c-basic-offset: 4
// indent-tabs-mode: nil
// End:
// vi: set et ts=4 sw=4 :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment