Reputation: 51
In this code I am trying to read all the data from the file using the fread()
function.
The problem is that nothing is read in the array.
How can fix the error?
#include <stdio.h>
void func(const char *srcFilePath)
{
FILE *pFile = fopen(srcFilePath, "r");
float daBuf[30];
if (pFile == NULL)
{
perror(srcFilePath);
} else {
while (!feof(pFile)) {
fread(daBuf, sizeof(float), 1, pFile);
}
}
for (int i = 0; i < 5; i++) {
printf(" daBuf = %f \n", daBuf[i]);
}
}
void main() {
const char inputfile[] = "/home/debian/progdir/input";
func(inputfile);
}
The input file has values like this:
1.654107,
1.621582,
1.589211,
1.557358,
1.525398,
1.493311,
1.483532,
1.483766,
1.654107,
Upvotes: 2
Views: 294
Reputation: 22062
You may be confusing binary representation
and ascii representation
of number. Here is a small code to generate a binary file using the
first 5 data in your input
file.
#include <stdio.h>
int main()
{
float x[5] = {1.654107, 1.621582, 1.589211, 1.557358, 1.525398};
char outfile[] = "output.bin";
FILE *fp;
if (NULL == (fp = (fopen(outfile, "wb")))) {
perror(outfile);
exit(1);
}
fwrite(x, sizeof(float), 5, fp);
fclose(fp);
return 0;
}
If you compile and execute it, a file output.bin
will be generated.
As you seem to be working on debian, try xxd
command to dump
the binary file:
$ xxd output.bin
0000000: c7b9 d33f 0090 cf3f 446b cb3f 8257 c73f ...?...?Dk.?.W.?
0000010: 3e40 c33f >@.?
The first 4-byte data c7b9d33f
corresponds to the first number
1.654107
. (Note the byte order depends on the endianness of the
processor architecture.)
In general we don't care what c7b9d33f
means because binary data
is not human readable. If you are interested in the format, search google
for IEEE754
. The important thing is fread()
and fwrite()
are
designed to read/write binary data.
Your posted program can be used to read output.bin
with some
corrections:
#include <stdio.h>
void func(const char *srcFilePath)
{
int i;
float daBuf[30];
FILE *pFile = fopen(srcFilePath, "rb");
if (pFile == NULL) {
perror(srcFilePath);
exit(1);
}
fread(daBuf, sizeof(float), 5, pFile); // read 5 float data in an array
for (i = 0; i < 5; i++) {
printf(" daBuf = %f \n", daBuf[i]); // print them
}
}
int main()
{
const char inputfile[] = "output.bin";
func(inputfile);
return 0;
}
Output:
daBuf = 1.654107
daBuf = 1.621582
daBuf = 1.589211
daBuf = 1.557358
daBuf = 1.525398
You still have a mistake in the usage of fread()
. You are
passing the fixed address daBuf
to fread()
in the loop
as fread(daBuf, sizeof(float), 1, pFile)
. It just modifies the
first element daBuf[0] repeatedly without assigning other elements.
You can read multiple elements of data at once by passing the length
as the 3rd argument to fread().
As you may have roughly grasped the binary data, let's go back to
ascii data. Try to dump your input
(w/o commas) with xxd
:
$ xxd input
0000000: 312e 3635 3431 3037 0a31 2e36 3231 3538 1.654107.1.62158
0000010: 320a 312e 3538 3932 3131 0a31 2e35 3537 2.1.589211.1.557
0000020: 3335 380a 312e 3532 3533 3938 0a31 2e34 358.1.525398.1.4
0000030: 3933 3331 310a 312e 3438 3335 3332 0a31 93311.1.483532.1
0000040: 2e34 3833 3736 360a 312e 3635 3431 3037 .483766.1.654107
0000050: 0a .
If you read the file input
by using fread()
, the first element
daBuf[0], for instance, will be assigned to 4-byte data 312e3635
,
which will be meaningless as a binary representation.
I hope you will have understood why you cannot use fread()
to
read ascii files.
Upvotes: 1
Reputation: 26375
Your file contains formatted text, so you can use fscanf
.
Ensure that you are reading data into a new position in the array every iteration, and that you do not go beyond the bounds of the array.
Use the return value of fscanf
to control your loop.
Notice the format string for fscanf
is "%f,"
.
#include <stdio.h>
#define BUFMAX 32
void func(const char *srcFilePath)
{
FILE *pFile = fopen(srcFilePath, "r");
if (!pFile) {
perror(srcFilePath);
return;
}
float daBuf[BUFMAX];
size_t n = 0;
while (n < BUFMAX && 1 == fscanf(pFile, "%f,", &daBuf[n]))
n++;
if (ferror(pFile))
perror(srcFilePath);
fclose(pFile);
for (size_t i = 0; i < n; i++)
printf("daBuf[%zu] = %f\n", i, daBuf[i]);
}
int main(void)
{
const char inputfile[] = "/home/debian/progdir/input";
func(inputfile);
}
daBuf[0] = 1.654107
daBuf[1] = 1.621582
daBuf[2] = 1.589211
daBuf[3] = 1.557358
daBuf[4] = 1.525398
daBuf[5] = 1.493311
daBuf[6] = 1.483532
daBuf[7] = 1.483766
daBuf[8] = 1.654107
fread
is generally intended for binary data, in which case you would open the file with the additional "b"
mode.
Here is an example, if your file contained binary data:
#include <stdio.h>
#define BUFMAX 32
void func(const char *srcFilePath)
{
FILE *pFile = fopen(srcFilePath, "rb");
if (!pFile) {
perror(srcFilePath);
return;
}
float daBuf[BUFMAX];
size_t n = fread(daBuf, sizeof *daBuf, BUFMAX, pFile);
if (ferror(pFile))
perror(srcFilePath);
fclose(pFile);
for (size_t i = 0; i < n; i++)
printf("daBuf[%zu] = %f\n", i, daBuf[i]);
}
int main(void)
{
const char inputfile[] = "/home/debian/progdir/input";
func(inputfile);
}
Upvotes: 1