fwrite doens't save full array in C - c++

I have an array of size 668x493 which i want to save. So i am doing the following.
data : is a pointer to an array that holds the values.
long lSize;
FILE* image_save;
image_save=fopen("image_save_file.bin","w+b");
fwrite(data,1,329324,image_save);
However, when i read back this array:
char* check_image;
p1File=fopen("image_save_file.bin","r+b");
fseek (p1File , 0 , SEEK_END);
lSize = ftell (p1File);
fseek (p1File , 0 , SEEK_SET);
when i check lSize, i see it 327680 ???
So of course when i do fread i get only 327680 values !
Kindly asking, can you pinpoint my mistake ?

Interestingly, 327680 is an exact multiple of 4096 (80 * 4096).
Are you flushing/closing the output file before you read the data back in?

The fwrite() function is buffered. Try flushing the data on the file stream and try again.

fwrite returns an int indicating the actual number of bytes written. Double check to make sure this differs from expected (it almost certainly does). Then, you can use perror to print out the error that's occurring.

Related

Copying binary jpg data into a buffer

void jpgToBuff(const char* srcfilename)
{
FILE* file = fopen(srcfilename, "rb");
fseek(file, 0, SEEK_END);
unsigned long fileLen = ftell(file);
fseek(file, 0, SEEK_SET);
char* file_data;
file_data = (char *)malloc((fileLen + 1) * sizeof(char));
fread(file_data, fileLen, 1, file);
fclose(file);
}
Am I doing this correctly. I want to eventually send this information through a socket and decode it on the other side. Any suggestions would be super helpful. Is this theoretically possible to send this through a socket and decode it into an image on the other side?
Well, you're not doing enough error checking. fopen, fseek, ftell, malloc, fread and fclose can all fail. Failures would likely result in a crash or other unexpected results.
fread might return fewer characters than you attempted to read, so you should probably check for that too.
You've allocated +1 byte, presumably so you could add a terminating '\0'? But you left that final byte uninitialized. A jpeg file could reasonably contain an embedded '\0', so adding a terminating '\0' is probably not going to get you the results you're hoping for.
Finally, sizeof(char) is defined by the standards to be 1, always. So, you might as well multiply by 1, or better yet, don't.
Other than that it looks basically right.

Produce garbage with using of fread

I would like to read the data with fread from file. However, I encounter the problem of setting of NULL terminator.I think the the line (fileMem[fileSize] = 0;) should have been solved. However, I still get rubbish at the with I check the value of "fileMem". Would anyone help me to find the problem?
I followed other posts about setting the NULL terminator but just does not work
File *input = fopen(filePath, "r");
fseek(input, 0, SEEK_END);
auto fileSize = ftell(input);
fseek(input, 0, SEEK_SET);
char* fileMem = new char[fileSize+1];
fileMem[fileSize] = 0;// the NULL terminator problem should have been solved here
clearerr(input);
fread(fileMem, fileSize,1, input);
What is the problem with my code?
fread is reading more bytes than fileSize, because you are specifying a record size of fileSize, and asking it to read only one text record. It then overwrites the 0 at the end with actual data, so you get garbage.
fread returns the number of bytes it actually read, so you can allocate a bigger buffer, then use the return value from fread to determine how much of it is valid (and to set a null-terminator).
Since it is updating your data in this way, I also suggest changing the file type to binary ("rb" rather than "r" in call to fopen).
The reason this is happening is because fread performs translation of text when in text mode ("r" rather than "rb"), such as carriage returns and line feeds.
Assuming you are on Windows, I think the problem is that you are opening the file in text mode and using fread which is meant for binary mode. In text mode, what you read may not be exactly what is in the file. Windows text files have "\r\n" at the end of the file, but in text mode this two character combination is converted to a single character, "\n". So the fileSize you computed will be too large and so your null terminator will be in the wrong place.
To verify this, change your fread to be:
int nr = fread( fileMen, 1, fileSize, input);
Swapping the middle args, will have fread return the number of bytes read. If you look at the value of nr, it will be smaller than fileSize because of the line end translation.
This wouldn't be a problem on a *nix system since there is no translation there in text mode.
When you want to use fread to read the contents of a file, you must open the file in binary mode.
FILE *input = fopen(filePath, "rb");
^^
Otherwise, the size of the file you get by using
fseek(input, 0, SEEK_END);
auto fileSize = ftell(input);
will be greater than the number of characters that what can be read by fread.
If you have a CR and a LF, they will count as two characters by the above method but fread will read only one character. Hence, fread will read less than fileSize characters. You can also change the fread line to:
// Swap the middle arguments.
// The first argument is supposed to be the size of each object.
// The second argument is supposed to be the number of objects to read.
auto n = fread(fileMem, 1, fileSize, input);
if ( n != fileSize )
{
// Surprise
}
fileMem[n] = '\0';

Size error on read file

RESOLVED
I'm trying to make a simple file loader.
I aim to get the text from a shader file (plain text file) into a char* that I will compile later.
I've tried this function:
char* load_shader(char* pURL)
{
FILE *shaderFile;
char* pShader;
// File opening
fopen_s( &shaderFile, pURL, "r" );
if ( shaderFile == NULL )
return "FILE_ER";
// File size
fseek (shaderFile , 0 , SEEK_END);
int lSize = ftell (shaderFile);
rewind (shaderFile);
// Allocating size to store the content
pShader = (char*) malloc (sizeof(char) * lSize);
if (pShader == NULL)
{
fputs ("Memory error", stderr);
return "MEM_ER";
}
// copy the file into the buffer:
int result = fread (pShader, sizeof(char), lSize, shaderFile);
if (result != lSize)
{
// size of file 106/113
cout << "size of file " << result << "/" << lSize << endl;
fputs ("Reading error", stderr);
return "READ_ER";
}
// Terminate
fclose (shaderFile);
return 0;
}
But as you can see in the code I have a strange size difference at the end of the process which makes my function crash.
I must say I'm quite a beginner in C so I might have missed some subtilities regarding the memory allocation, types, pointers...
How can I solve this size issue?
*EDIT 1:
First, I shouldn't return 0 at the end but pShader; that seemed to be what crashed the program.
Then, I change the type of reult to size_t, and added a end character to pShader, adding pShdaer[result] = '/0'; after its declaration so I can display it correctly.
Finally, as #JamesKanze suggested, I turned fopen_s into fopen as the previous was not usefull in my case.
First, for this sort of raw access, you're probably better off
using the system level functions: CreateFile or open,
ReadFile or read and CloseHandle or close, with
GetFileSize or stat to get the size. Using FILE* or
std::filebuf will only introduce an additional level of
buffering and processing, for no gain in your case.
As to what you are seeing: there is no guarantee that an ftell
will return anything exploitable as a numeric value; it could
very well be just a magic cookie. On most current systems, it
is a byte offset into the physical file, but on any non-Unix
system, the offset into the physical file will not map directly
to the logical file you are reading unless you open the file in
binary mode. If you use "rb" to open the file, you'll
probably see the same values. (Theoretically, you could get
extra 0's at the end of the file, but practically, the OS's
where that happened are either extinct, or only used on legacy
mainframes.)
EDIT:
Since the answer stating this has been deleted: you should loop
on the fread until it returns 0 (setting errno to 0 before
each call, and checking it after the return to see whether the
function returned because of an error or because it reached the
end of file). Having said this: if you're on one of the usual
Windows or Unix systems, and the file is local to the machine,
and not too big, fread will read it all in one go. The
difference in size you are seeing (given the numerical values
you posted) is almost certainly due to the fact that the two
byte Windows line endings are being mapped to a single '\n'
character. To avoid this, you must open in binary mode;
alternatively, if you really are dealing with text (and want
this mapping), you can just ignore the extra bytes in your
buffer, setting the '\0' terminator after the last byte
actually read.

C++ fwrite corrupts binary file

I'm trying to open an exe file and place input taken from the user and replace existing data (overwriting it) of the same length at specific locations. I can do this with my code, but I'm seeing data corruption in other parts of my file. This is my first time with C++, I've tried looking at everything I could to help myself, but I'm at a loss. Only thing I can think is that its related to a null string char at the end of 'char test1[100];' (If I read the documentation right). But doesnt help my issue of resolving the issue. See linked image for example from Hex Viewer of Output and Original
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *key;
key=fopen ("Testfile.exe","r+b");
char test1[100];
char test2[100];
printf("Test data to input:");
fgets(test1, sizeof test1, stdin);
printf("Second test data to input:");
fgets(test2, sizeof test2, stdin);
fseek (key,24523,SEEK_SET); //file offset location to begin write
fwrite (test1,1,sizeof(test1),key);
fseek (key,24582,SEEK_SET); //file offset location to begin write
fwrite (test2,1,sizeof(test2),key);
fseek (key,24889,SEEK_SET); //file offset location to begin write
fwrite (test2,1,sizeof(test2),key);
fclose(key);
printf ("Finished");
return(0);
}
After my initial edits, I was still fighting with a Null Terminator being written at the end of my string (and thus affecting operation of the edited exe file). After a bit more reading this is my final solution that works as intended without any weird data being written. I used scanf ("%10s") to ensure only my string was being used and to get rid of any Null Terminator. Does anyone see anything majorly wrong here or improvements to be made? Eventually I'd like to implement string length checking to ensure proper length was input by user. Thanks for everyone's help.
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *key;
key=fopen ("test.exe","r+b");
char test1[10];
char test2[32];
printf("Input Test1 data:");
scanf ("%10s",test1); //only read 10 Chars
printf("Input test2 data:");
scanf ("%32s",test2); //only read 32 Chars
fseek (key,24523,SEEK_SET); //file offset location to begin write
fputs (test1,key);
fseek (key,24582,SEEK_SET); //file offset location to begin write
fputs (test2,key);
fseek (key,24889,SEEK_SET); //file offset location to begin write
fputs (test2,key);
fclose(key);
printf ("Finished");
return(0);
}
It looks like you're to write a string into the exe file but actually you're writing a string padded with garbage values up to a length of 100 bytes.
If you just want to write the string, replace fwrite with fputs.
sizeof(array) gives the allocated size of the static array (100 in this case) , not the string length. string length is done via strlen() which doesn't include the terminating NULL character.
You have two problems.
First: you're writing 100 byte buffers which have not been initialized except via fgets()... everything not put in there by fgets() is whatever happened to be in memory (on the stack in this case).
Second: you're writing 100 bytes with each write however your seek does not advance to at least 100 bytes later, meaning the second write() in this snippet partially overwrites the first.

Binary files in C++

I want to store data from desired byte upto another desired byte of the file opened in binary mode in to another file. Lets say file pointer is at byte# 10, now i want to read data from byte # 11 to byte # 30. I know i have to use fread() function but don't know how to tell this function to read from desired location upto another desired location. I am a beginner so bear answering this question.
I know fread() is C function, I want C++ equivalent functions for doing this work. A link or suggestion of book for learning file handling will be great!
Thanks alot for your help!
You have to seek:
std::ifstream infile("source.bin", std::ios::binary);
infile.seekg(10, std::ios::beg); // seek to 10 bytes from the beginning
char buf[20];
if (!infile.read(buf, 20)) { /* error */ }
// now your data is in buf
The stdio interface is is similar, but since this is C++, we prefer the iostreams one. You must never, ever use I/O operations without checking their return value, and in iostreams this is fairly easy. With fread you have to be careful to interpret the return value correctly.
Well, the prototype for fread is :
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
And fseek is:
int fseek ( FILE * stream, long int offset, int origin );
If you want to get to byte #11, you can do:
fseek(file, 11, SEEK_SET) // this means: go 11 bytes from the start position.
or, since you're already at byte 10, you can do:
fseek(file, 1, SEEK_CUR) // this means: go 1 byte beyond current position.
Then, to read up to byte 30 from byte 11, you need to read 19 bytes (30 - 11), so you do:
fread(buffer, sizeof(char), 19, file).