Sujet : Re: Whaddaya think?
De : nospam (at) *nospam* dfs.com (DFS)
Groupes : comp.lang.cDate : 16. Jun 2024, 16:52:30
Autres entêtes
Message-ID : <666f0a3e$0$1412896$882e4bbb@reader.netnews.com>
References : 1 2
User-Agent : Betterbird (Windows)
On 6/15/2024 6:03 PM, Ben Bacarisse wrote:
DFS <nospam@dfs.com> writes:
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
>
Any issues with this method?
There are two issues: (1) you end up with a program that can't be
"piped" to (because the input can't be rewound), and (2) the file might
change between counting and reading. How much either matters will
depend on the context. I like piping to programs so (1) would bother
me.
Any 'better' way?
I'd allocate the array on the fly. It's one of those things that, once
you've done it, becomes a stock bit of coding. In fact, you can write a
simple dynamic array module, and use it again and again.
----------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
>
int main(int argc, char *argv[]) {
>
int N=0, i=0, j=0;
int *nums;
FILE* datafile = fopen(argv[1], "r");
while(fscanf(datafile, "%d", &j) != EOF){
It's always better to loop while fscanf succeeds rather than trying to
handle all the errors. You might not care about case where this loop
fails, but it's just better to get into the right habit:
while (fscanf(datafile, "%d", &j) == 1) ...
nums = calloc(N, sizeof(int));
The cost is low, but there's no need to use calloc here as you are going
to assign exactly N locations.
rewind(datafile);
while(fscanf(datafile, "%d", &j) != EOF){
nums[i++] = j;
}
As above, though I'd read into &nums[i] directly.
fclose (datafile);
printf("\n");
for(i=0;i<N;i++) {
printf("%d. %d\n", i+1, nums[i]);
}
printf("\n");
free(nums);
return(0);
Because I have acquired the habit, I'd also check for errors,
particularly on argc, fopen and malloc.
}
----------------------------------------------------------
Thanks for the tips.
I'm not into error checking on my personal code. But I am into brief and efficient.
New effort
* dropped 2 variables
* allocate 'on the fly'
* one fscanf thru the file
* 4 less lines of code
----------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int N=0;
int *nums = malloc(2 * sizeof(int));
FILE* datafile = fopen(argv[1], "r");
while(fscanf(datafile, "%d", &nums[N++]) == 1){
nums = realloc(nums, (N+1) * sizeof(int));
}
fclose (datafile);
N--;
for(int i=0;i<N;i++) {
printf("%d.%d ", i+1, nums[i]);
}
free(nums);
printf("\n");
return 0;
}
----------------------------------------------------------
original 19 lines not incl close brackets
----------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int N=0, i=0, j=0;
int *nums;
FILE* datafile = fopen(argv[1], "r");
while(fscanf(datafile, "%d", &j) != EOF){
N++;
}
nums = calloc(N, sizeof(int));
rewind(datafile);
while(fscanf(datafile, "%d", &j) != EOF){
nums[i++] = j;
}
fclose (datafile);
printf("\n");
for(i=0;i<N;i++) {
printf("%d. %d\n", i+1, nums[i]);
}
printf("\n");
free(nums);
return(0);
}
----------------------------------------------------------