| 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"