You are slightly off-target on what you have in your input file. Your input file provides the number of 32-bit integers contained in the file as the first value. You need only read the first integer to know how much storage you need to allocate for the remaining values.
Rather then using a typedef
to a signed 32-bit integer, the standard C library provides the stdint.h
header with all exact-width types, including the signed 32-bit type already provided as int32_t
. The inttypes.h
header provides the macros for printing and reading the exact width types (e.g. PRId32
for printing where d
can be u
unsigned, x
hexadecimal, o
octal, or i
integer, and e.g. SCNd32
for use with scanf)
Therefore, all you really need to do is open the file for reading (using "rb"
as the mode for portabilty, the 'b'
doesn't do anything and is provided for C89 compatibility) You open the file and read the first 32-bit value into a variable. That tells you how many 32-bit values follow -- and leaves the file position indicator ready to read the remaining values, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main (int argc, char **argv) {
int32_t *a = NULL, nint = 0; /* pointer and no. of int */
/* use filename provided as 1st argument ("000002.dat" by default) */
FILE *fp = fopen (argc > 1 ? argv[1] : "000002.dat", "rb");
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* read no. of int32_t values from 1st value in file */
if (fread (&nint, 1, sizeof nint, fp) != sizeof nint) {
perror ("fread-nint");
return 1;
}
...
Now simply allocate storage for the remaining values, either with malloc()
(recommended), or you can declare a Variable Length Array but you should check the number of values to ensure you don't attempt to declare an array that exceeds your stack size -- which will be compiler/OS dependent. MS usually provides a 1M stack, so you should be able to declare a VLA of about 200K integers -- balanced against whatever other stack use you have. A simple dynamic allocation with malloc
will eliminate the risk of StackOverflow...
...
/* allocate/validate storage */
if (!(a = malloc (nint * sizeof nint))) {
perror ("malloc-a");
return 1;
}
...
All that remains is reading the rest of the values from your file with fread
. The fread
function reads a number of blocks of a given size storing the results in the address provided. So you simply want to read nint
values of sizeof nint
(or you could use sizeof *a
- both are the same type). The return will be the number of blocks of that size read from the file. You can read the remaining values with:
...
/* read remaining values from file into a */
if (fread (a, sizeof nint, (size_t)nint, fp) != (size_t)nint) {
perror ("fread-a");
return 1;
}
fclose (fp); /* close file */
...
(note: always VALIDATE that your allocation succeeds, and validate your read from the file by checking the return of fread
.)
A complete example that confirms the number of 32-bit values read from the file could be:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main (int argc, char **argv) {
int32_t *a = NULL, nint = 0; /* pointer and no. of int */
/* use filename provided as 1st argument ("000002.dat" by default) */
FILE *fp = fopen (argc > 1 ? argv[1] : "000002.dat", "rb");
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* read no. of int32_t values from 1st value in file */
if (fread (&nint, 1, sizeof nint, fp) != sizeof nint) {
perror ("fread-nint");
return 1;
}
/* allocate/validate storage */
if (!(a = malloc (nint * sizeof nint))) {
perror ("malloc-a");
return 1;
}
/* read remaining values from file into a */
if (fread (a, sizeof nint, (size_t)nint, fp) != (size_t)nint) {
perror ("fread-a");
return 1;
}
fclose (fp); /* close file */
/* report number of integers read */
printf ("%d int32_t read from file.\n", nint);
}
Example Use/Output
Using the file you provided the link to, and passing the filename to read as the first argument to the program (or reading from the file in the current directory by default), you would get:
$ ./bin/freadint32_t ../dat/000002.dat
892 int32_t read from file.
Values In File
If you output the values in the file by adding a simple loop, you would find:
16 25 22 11 17 20 19 23 22 16
17 22 25 25 18 22 24 17 15 18
25 14 14 29 16 14 23 23 21 20
28 24 17 22 18 21 22 24 27 16
16 21 22 30 28 18 23 20 15 23
20 19 22 22 23 20 18 20 28 22
21 22 20 30 21 17 24 22 21 18
19 20 20 25 22 20 30 26 25 33
21 15 23 22 19 17 17 20 21 21
27 35 27 19 21 22 19 13 18 18
12 20 25 22 24 21 20 26 22 24
30 22 18 22 20 16 18 23 22 24
23 17 22 22 17 23 22 16 24 25
20 18 18 25 24 23 22 17 23 26
22 16 17 25 27 24 23 26 23 20
24 17 10 23 22 13 20 16 16 22
18 23 25 20 28 24 21 26 22 24
22 24 25 19 26 28 21 18 21 25
24 19 20 21 19 20 19 19 18 29
...
25 23 18 19 25 23 19 23 22 18
22 19 16 15 13 25 26 23 26 20
23 16 14 23 20 23 22 24 26 19
20 18
All 892 values read.
Look things over and let me know if you have further questions.