arrays - Reading a file in C and passing the contents to main() -
i'm new c. i'm having issue accessing data read in file. idea behind i'm trying text file, read in, create array , set contents of array equal contents of file (the characters).
now, here confused. manipulate tstr
in main method, need able access contents set in read method. if try access tstr
array in main class, understanding, wont able considering have set size of passed no values it.
if want edit array tstr
should contain contents of text file how data readfile()
main()
#include <stdio.h> #include <stdlib.h> #define size 1000 int readfile(char fn[], char tstr[]); int main(int argc, char* argv[]){ char tstr[size]; return 0; } int readfile(char fn[], char tstr[]) { file *fptr; char c; int = 0; if ((fptr=fopen(fn, "r")) == null){ printf("error: unknown file %s\n", fn); exit(1); } while ((c = fgetc(fptr)) != eof) tstr[i++] = c; tstr[i] = '\0'; return i; }
sometimes, there reason able call function read file , have function return pointer allocated array of strings holding file's contents. true when have no idea how long file is. while can pass pointer, required ***
argument handle realloc
changing pointer address in of reallocation.
declaring function char **
, having return pointer allocated array standard way of handling situation. additionally, choosing reasonable number of pointers allocate , following standard reallocation scheme (on realloc
, allocate 2x
number of current pointers) avoids costly , relatively expensive calls realloc
seen when calling realloc
each line in file.
when dynamically allocate memory, keep track of memory, preserve pointer start of memory block (so can free
it), , free
memory when no longer needed.
the following puts puzzle pieces in short example. example uses getline
read lines file , strdup
(which allocates memory , copies) copy lines read getline
array of strings. let me know if have questions:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define nmax 256 char **readtxtfile (char *fn, size_t *idx); void prn_chararray (char **ca); void free_chararray (char **ca); int main (int argc, char **argv) { size_t file_size = 0; /* placeholders filled readtxtfile */ char *fn = argc > 1 ? argv[1] : null; /* read each file array of strings, number of lines read, returned in file_size */ char **file = readtxtfile (fn, &file_size); /* output number of lines read , */ printf ("\n read '%zu' lines file: %s\n\n", file_size, fn ? fn : "stdin"); /* simple print function */ if (file) prn_chararray (file); /* simple free memory function */ if (file) free_chararray (file); return 0; } char **readtxtfile (char *fn, size_t *idx) { char *ln = null; /* null forces getline allocate */ size_t n = 0; /* size of ln, 0 - getline decides */ ssize_t nchr = 0; /* number of chars read */ size_t nmax = nmax; /* check reallocation */ char **array = null; /* array hold lines read */ file *fp = null; /* file pointer open file fn */ /* open / validate file or read stdin */ if (fn) { if (!(fp = fopen (fn, "r"))) { fprintf (stderr, "%s() error: file open failed '%s'.", __func__, fn); return null; } } else fp = stdin; /* allocate nmax pointers char* */ if (!(array = calloc (nmax, sizeof *array))) { fprintf (stderr, "%s() error: memory allocation failed.", __func__); return null; } /* read each line stdin - dynamicallly allocated */ while ((nchr = getline (&ln, &n, fp)) != -1) { /* strip newline or carriage rtn */ while (nchr > 0 && (ln[nchr-1] == '\n' || ln[nchr-1] == '\r')) ln[--nchr] = 0; array[*idx] = strdup (ln); /* allocate/copy ln array */ (*idx)++; /* increment value @ index */ if (*idx == nmax) { /* if lines exceed nmax, reallocate */ char **tmp = realloc (array, nmax * 2); if (!tmp) { fprintf (stderr, "%s() error: reallocation failed.\n", __func__); exit (exit_failure); /* or return null; */ } array = tmp; nmax *= 2; } } if (ln) free (ln); /* free memory allocated getline */ if (fp != stdin) fclose (fp); /* close open file descriptor */ return array; } /* print array of character pointers. */ void prn_chararray (char **ca) { register size_t n = 0; while (ca[n]) { printf (" arr[%3zu] %s\n", n, ca[n]); n++; } } /* free array of char* */ void free_chararray (char **ca) { if (!ca) return; register size_t n = 0; while (ca[n]) free (ca[n++]); free (ca); }
output
$ /bin/getline_readfile_function <~/tmp/fc-list-fonts-sorted-no-path.txt read '187' lines file: stdin arr[ 0] andalemo.ttf: andale mono - regular arr[ 1] arialbd.ttf: arial - bold arr[ 2] arialbi.ttf: arial - bold italic arr[ 3] ariali.ttf: arial - italic arr[ 4] arialnbi.ttf: arial arr[ 5] arialnb.ttf: arial arr[ 6] arialni.ttf: arial arr[ 7] arialn.ttf: arial arr[ 8] arial.ttf: arial - regular arr[ 9] arialuni.ttf: arial unicode ms - regular arr[ 10] ariblk.ttf: arial arr[ 11] bailey script regular.ttf: bailey script - regular arr[ 12] bailey_script_regular.ttf: bailey script - regular arr[ 13] belwe gotisch.ttf: belwe gotisch - regular arr[ 14] belwe_gotisch.ttf: belwe gotisch - regular <snip>
memory check
$ valgrind ./bin/getline_readfile_function <~/tmp/fc-list-fonts-sorted-no-path.txt ==20259== memcheck, memory error detector ==20259== copyright (c) 2002-2012, , gnu gpl'd, julian seward et al. ==20259== using valgrind-3.8.1 , libvex; rerun -h copyright info ==20259== command: ./bin/getline_readfile_function ==20259== read '187' lines file: stdin arr[ 0] andalemo.ttf: andale mono - regular arr[ 1] arialbd.ttf: arial - bold arr[ 2] arialbi.ttf: arial - bold italic arr[ 3] ariali.ttf: arial - italic <snip> ==20259== ==20259== heap summary: ==20259== in use @ exit: 0 bytes in 0 blocks ==20259== total heap usage: 189 allocs, 189 frees, 9,831 bytes allocated ==20259== ==20259== heap blocks freed -- no leaks possible ==20259== ==20259== counts of detected , suppressed errors, rerun with: -v ==20259== error summary: 0 errors 0 contexts (suppressed: 2 2)
note: if pointer fn
passed readtxtfile
null
, input read stdin
. (this adds flexibility input routine) call above have been:
./bin/getline_readfile_function ~/tmp/fc-list-fonts-sorted-no-path.txt
Comments
Post a Comment