Deutsch English Français Italiano |
<v5ev8k$1l548$1@dont-email.me> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Lew Pitcher <lew.pitcher@digitalfreehold.ca> Newsgroups: comp.lang.c Subject: Re: Whaddaya think? Date: Tue, 25 Jun 2024 17:37:24 -0000 (UTC) Organization: A noiseless patient Spider Lines: 142 Message-ID: <v5ev8k$1l548$1@dont-email.me> References: <666ded36$0$958$882e4bbb@reader.netnews.com> <v4n1nf$2fae$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Injection-Date: Tue, 25 Jun 2024 19:37:24 +0200 (CEST) Injection-Info: dont-email.me; posting-host="378c0296351914fa8a558aaf0b11785d"; logging-data="1741960"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Sn8FpHylzGORczEp/zgcvelvamGA+ZQw=" User-Agent: Pan/0.139 (Sexual Chocolate; GIT bf56508 git://git.gnome.org/pan2) Cancel-Lock: sha1:KnmoWlSa6IbVev6/Vbln1QXdyoM= Bytes: 5127 On Sun, 16 Jun 2024 15:52:16 +0000, Lew Pitcher wrote: > On Sat, 15 Jun 2024 15:36:22 -0400, DFS wrote: > >> I want to read numbers in from a file, say: >> >> 47 185 99 74 202 118 78 203 264 207 19 17 34 167 148 54 297 271 118 245 >> 294 188 140 134 251 188 236 160 48 189 228 94 74 27 168 275 144 245 178 >> 108 152 197 125 185 63 272 239 60 242 56 4 235 244 144 69 195 32 4 54 79 >> 193 282 173 267 8 40 241 152 285 119 259 136 15 83 21 78 55 259 137 297 >> 15 141 232 259 285 300 153 16 4 207 95 197 188 267 164 195 7 104 47 291 >> >> >> This code: >> 1 opens the file >> 2 fscanf thru the file to count the number of data points >> 3 allocate memory >> 4 rewind and fscanf again to add the data to the int array >> >> [snip] > You /could/ create a temporary, binary, file, and write the fscanf()'ed > values to it as part of the first loop. Once the first loop completes, > you rewind this temporary file, and load your integer array by reading > the (now converted to native integer format) values from that file. > > Still two passes, but using fscanf() in only one of those passes. [snip] For what it's worth, here's an example of what I suggest: /* The following code provides two examples of the approach I suggested. Example 1: while counting input numbers, write temp file with int values malloc() a buffer big enough for that count of int values fread() the temp file into the malloc()'ed buffer Note: conformant to ISO Standard C. Example 2: while counting input numbers, write temp file with int values mmap() the temp file, starting at the beginning, and sized to include all the int values in the file. Note: conformant to POSIX C extensions to ISO Standard C. Note: compile with -DUSE_MMAP to obtain mmap() variant, otherwise this will compile the malloc()/fread() variant */ #include <stdio.h> #include <stdlib.h> #ifdef USE_MMAP #include <sys/mman.h> #define BANNER "Example of array loading using mmap()" #define FREEALLOC(x) #else #define BANNER "Example of array loading using malloc() and fread()" #define FREEALLOC(x) free((x)) #endif static int *LoadIntArray(FILE *fp, size_t *Count); int main(void) { int status = EXIT_FAILURE, *array; size_t count; puts(BANNER); if ((array = LoadIntArray(stdin,&count))) { printf("%zu elements loaded\n",count); for (size_t index = 0; index < count; ++index) printf("array[%3zu] == %d\n",index,array[index]); FREEALLOC(array); /* if necessary, free() the malloc()'ed array */ status = EXIT_SUCCESS; } return status; } static int *LoadIntArray(FILE *fp,size_t *Count) { FILE *tmp; int *array = NULL; size_t count = 0; if ((tmp = tmpfile())) { int buffer; for (count = 0; fscanf(fp,"%d",&buffer) == 1; ++count) fwrite(&buffer,sizeof buffer, 1,tmp); if (count) { #ifdef USE_MMAP /* ** USE mmap() to map temp_file data into process memory */ array = mmap(NULL, count * sizeof *array, PROT_READ,MAP_PRIVATE, fileno(tmp), 0); if (array == MAP_FAILED) { array = NULL; fprintf(stderr,"FAIL: Cannot mmap %zu element array\n",count); } #else /* ** USE malloc() to reserve a big enough heap-space buffer, ** then fread() the temp_file data into that buffer */ if ((array = malloc(count * sizeof *array))) { rewind(tmp); if (fread(array,sizeof *array,count,tmp) != count) { free(array); array = NULL; fprintf(stderr,"FAIL: Cannot load %zu element array\n",count); } } else fprintf(stderr,"FAIL: Cant malloc() %zu element array\n",count); #endif } fclose(tmp); } else fprintf(stderr,"FAIL: Cannot allocate temporary work file\n"); *Count = count; /* byproduct value that caller might find useful */ return array; /* either NULL (on failure) or pointer to array */ } -- Lew Pitcher "In Skills We Trust"