Reputation: 2323
In C, I am reading the entire contents of the file Data_A into a buffer created with malloc(). The file contains 1000 random integers in the range 5 to 1000.
When I read the file, the newLen variable (see below) shows that the read size is 1001. When I iterate over it as shown below, I get valid numbers (each number correctly corresponds to what's in the file), until it reaches 250 where it returns a negative number. Obviously it read only 251 integers from a file of 1000 integers, but I don't know why. Here's the code:
char FileA [] = "C:/C_Projects/Data_A";
int *buffer1 = NULL;
FILE *pRead;
FILE *fp = fopen(FileA, "rb");
FILE *ptr_test;
fseek(fp, 0L, SEEK_END);
long bufsize = ftell(fp);
buffer1 = malloc(bufsize + 1);
fseek(fp, 0, SEEK_SET);
int nums_to_read = bufsize / 4;
size_t newLen = fread(buffer1, 1, nums_to_read, fp);
buffer1[++newLen] = '\0';
fclose(fp);
// Iterate
int i;
int abc;
int bcd;
for (i = 0; i < bufsize / 4; i++)
{
abc = buffer1[i];
if (abc < 0)
{
bcd = 0;
}
if (i >= 200)
{
bcd = 0;
}
}
As I said, all numbers in the file are positive numbers between 5 and 1000; there are no zeroes or negative numbers. So I don't understand why it's not reading all 1000 integers. The variable bufsize confirms that the buffer is 4000 bytes.
Any ideas will be most appreciated.
Upvotes: 1
Views: 3086
Reputation: 50210
the error is here
int nums_to_read = bufsize / 4;
size_t newLen = fread(buffer1, 1, nums_to_read, fp);
the second param to fread is the size of the elements to read. the third is how many to read. It seems you intent is to read 4 bytes numbers (since you divieded the length by 4). So you should say
int nums_to_read = bufsize / 4;
size_t newLen = fread(buffer1, 4, nums_to_read, fp);
This skip over the whole issue of - are your ints 4 bytes. And is the file really raw 4 bytes ints.
Upvotes: 0
Reputation: 154169
Code has various problems and weaknesses, the biggest was a scant read. @Marcus Müller @Retired Ninja
1 was too small an element size
// fread(buffer1, 1, nums_to_read, fp);
// read nums_to_read elements
// Each elements has the size of `sizeof buffer[0]`
fread(buffer1, sizeof buffer[0], nums_to_read, fp);
Other improvements in code. Handle_Error()
is some error handling code to be written.
char FileA [] = "C:/C_Projects/Data_A";
// FILE *pRead; // not used here
FILE *fp = fopen(FileA, "rb");
if (fp == NULL) Handle_Error();
// FILE *ptr_test; // not used here
fseek(fp, 0, SEEK_END);
long bufsize = ftell(fp);
if (bufsize == -1) Handle_Error();
int *buffer1 = malloc(bufsize + sizeof *buffer1);
if (buffer1 == NULL) Handle_Error();
// fseek(fp, 0, SEEK_SET);
rewind(fp); // rewind is sufficient and more clear
// int nums_to_read = bufsize / 4;
size_t nums_to_read = (size_t) bufsize / sizeof *buffer1;
size_t newLen = fread(buffer1, sizeof buffer[0], nums_to_read, fp);
if (newLen != nums_to_read) Handle_Error();
// buffer1[++newLen] = '\0';
buffer1[newLen] = 0;
fclose(fp);
int bcd = 1; // likely should have a default value
// Iterate
// for (int i = 0; i < (size_t) bufsize / 4; i++) {
for (size_t i = 0; i < newLen; i++) {
int abc = buffer1[i];
if (abc < 0) {
bcd = 0;
}
if (i >= 200) {
bcd = 0;
}
}
Upvotes: 1
Reputation: 2323
I answered this in the final comment above, but to make this post appear as an answered question, I am posting this here too. Changing the fread line to size_t newLen = fread(buffer1, sizeof(int), nums_to_read, fp);
corrected the problem and now it reads the entire file.
Thanks very much to @Retired Ninja and the others who replied to this question.
Upvotes: 0