/*
Will read a file from disk while dynamically allocating memory.
Example usage: ./exe [file-name]
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct string_t {
int memsize;
int length;
char *text;
int error;
};
typedef struct string_t string;
string redfile(FILE *file);
void str_dump(string *s);
string redfile(FILE *file) {
int charsize = sizeof(char);
int charcount = 0;
int blocksize = 10;
int memsize = blocksize;
char *line = (char*) malloc(charsize * (memsize+1));
char *linep = line;
string l;
l.error = 0;
l.length = 0;
l.memsize = memsize;
l.length = charcount;
l.text = linep;
while (1) {
if(charcount > memsize) {
// reallocate memmory
memsize = memsize+blocksize;
char *al = realloc(linep, charsize * (memsize+1));
if (al == NULL) {
fprintf(stderr, "Error, out of memory.\n");
*line = '\0';
l.text = linep;
l.error = 1;
return l;
}
}
char c = fgetc(file);
//if (c == '\n' || c == '\r' || c == EOF) {
if (c == EOF) {
charcount--;
break;
}
// remember input char
*line = c;
*(line++);
charcount++;
}
*line = '\0';
l.text = linep;
l.memsize = memsize;
l.length = charcount;
return l;
}
void str_dump(string *s) {
if (s->error == 0) {
printf("memsize: %d\n", s->memsize);
printf("length: %d\n", s->length);
printf("error: %d\n", s->error);
printf("text: %s\n", s->text);
printf("total: %lu\n", sizeof(*s)+1);
} else
printf("Error: %d.\n", s->error);
}
int main(int argc, char **argv) {
// string l = redfile(stdin);
if(argc < 2) {
fprintf(stderr, "Usage: %s [file]\n", argv[0]);
exit(1);
}
FILE *f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "Error: failed to open file: %s\n", argv[1]);
exit(2);
}
string l = redfile(f);
if (l.error != 0) {
fprintf(stderr, "Error: redfile() error: '%d'\n", l.error);
fclose(f);
exit(l.error);
}
str_dump(&l);
fclose(f);
exit(0);
}