Path: ...!news-out.netnews.com!postmaster.netnews.com!us4.netnews.com!not-for-mail X-Trace: DXC=C=7hQXbBmaXTBYNk3=OSRZHWonT5<]0T]Q;nb^V>PUfV5[gZBW6J?L\ZHjmnLVPdB]k4G3cSPE1c_nT`JO7@`Z@PMba][>SC2CWf;]EoU=id5V=R <87sexdx3s1.fsf@bsb.me.uk> Content-Language: en-US From: DFS In-Reply-To: <87sexdx3s1.fsf@bsb.me.uk> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Lines: 151 Message-ID: <666f0a3e$0$1412896$882e4bbb@reader.netnews.com> NNTP-Posting-Host: 127.0.0.1 X-Trace: 1718553150 reader.netnews.com 1412896 127.0.0.1:35667 Bytes: 4989 On 6/15/2024 6:03 PM, Ben Bacarisse wrote: > DFS 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 >> #include >> >> 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> 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 #include 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 #include 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