I have question about fprintf and fwrite.
How many bytes are written when this code runs (assuming fp has been correctly set up).
int i = 10000;
fprintf(fp,"%d",i);
fwrite(fp,sizeof(int),1,&i);
When I checked then 5 bytes and 9 bytes respectively. Maybe I am wrong. I thought it is 4 bytes since int. Can someone explain please??? Thanks.
fprintf writes the string 10000 (5 bytes) to the file, while fwrite writes binary representation of 10000 (sizeof(int) bytes) to the file.
How are you checking the number of bytes written? sizeof(int) depends on platform.
Given below is the function signature for fwrite.
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
fwrite writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to stream. The return value gives the actual number of bytes written. Mostly it is going to be size * count.
Similarly fprintf returns the number of characters written/printed.
fprintf(fp,"%d",i); writes 5 bytes. it writes 10000 as string, 5 chars
Related
I am writing some software that corrupts files. It stores the file in a buffer, corrupts that buffer by xoring it with random masks, then writes the modified buffer to stdout so that the (linux) user can pipe it to somewhere.
I have opened stdout in binary mode:
FILE *const out = fdopen(dup(fileno(stdout)), "wb");
But how do I actually write the whole buffer to out in one go?
It seems I have 2 options:
Iterate all bytes and do fputc
Hope that there are no nullbytes in the data and do fputs
I'm looking for a fputb which takes:
A pointer to the data to be written
A file descriptor to write it to
The amount of bytes to write
(with better performance than a fputc-loop)
You're looking for fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ):
Writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to the current position in the stream.
I am trying to understand how the fread() function in <stdio.h> works and I am confused about the return value of this function. In the man pages it says
RETURN VALUE
On success, fread() and fwrite() return the number of items read
or written. This number equals the number of bytes transferred only
when size is 1. If an error occurs, or the end of the file is
reached, the return value is a short item count (or zero).
fread() does not distinguish between end-of-file and error, and
callers must use feof(3) and ferror(3) to determine which occurred.
Could someone please explain to me what is meant by number of items read or written in this context. Also can anyone provide me with some example return values and their meanings?
fread() will read a count of items of a specified size from the provided IO stream (FILE* stream). It returns the number of items successfully read from the stream. If it returns a number less than the requested number of items, the IO stream can be considered empty (or otherwise broken).
The number of bytes read will be equal to the number of items successfully read times the provided size of the items.
Consider the following program.
#include <stdio.h>
int main() {
char buf[8];
size_t ret = fread(buf, sizeof(*buf), sizeof(buf)/sizeof(*buf), stdin);
printf("read %zu bytes\n", ret*sizeof(*buf));
return 0;
}
When we run this program, depending on the amount of input provided, different outcomes can be observed.
We can provide no input at all. The IO stream will be empty to begin with (EOF). The return value will be zero. No items have been read. Zero is returned.
$ : | ./a.out
read 0 bytes
We provide fewer input as requested. Some items will be read before EOF is encountered. The number of items read is returned. No more items are available. Thereafter the stream is empty.
$ echo "Hello" | ./a.out
read 6 bytes
We provide equal or more input as requested. The number of items as requested will be returned. More items may be available.
$ echo "Hello World" | ./a.out
read 8 bytes
Related reading:
What is the rationale for fread/fwrite taking size and count as arguments?
When there are less bytes in the stream than consitute an item, the number of bytes consumed from the stream might however be greater than the number of bytes read as calculated by above formula. This answer to above linked question (and the comment to it) I find especially insightful in this matter:
https://stackoverflow.com/a/296305/1025391
The syntax for fread() is
size_t fread(void *ptr, size_t size, size_t nmemb, FILE * stream );
which means,
The function fread() reads nmemb elements of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.
So, the total number of bytes read will be nmemb * size.
Now, by saying
on success, fread() and fwrite() return the number of items read or written. This number equals the number of bytes transferred only when size is 1.
it means that, the return value will equal the nmemb when the size is 1.
Logic is same, in case of fwrite() also.
EDIT
for example, a fully successful call to fread() like
fread(readbuf, sizeof(int), 5 , stdin);
will return 5 while it will read sizeof(int) * 5 bytes. If we assume sizeof(int) is 4, then total bytes read will be 5 * 4 or 20. As you can see, here, the number of items read or written is not equal to the number of bytes transferred.
OTOH, another fully successful call to fread() like
fread(readbuf, sizeof(char), 5 , stdin);
will also return 5 while it will read sizeof(char) * 5 bytes, i.e., 5 bytes. In this case, as sizeof(char) is 1, so, here, the number of items read or written is equal to the number of bytes transferred. i.e., 5.
I want to read a video file and save as binary and write as a video file again.
I tested with 180MB video. I used fread function and It occur segmentation fault because array size is small for video.
those are my questions:
I use 160*1024 bytes char array. What is the maximum size of char array? How I can solve this problem?
this program need to work as:
read 128 bytes of video -> Encrypt -> write 128 byte
read next 128 bytes -> Encrypt -> write to the next.
I can't upload my code because of security rule of company. Any tip would be appreciated.
first use fseek() with SEEK_END, then use ftell() to determine the file size, after that allocate the needed memory with malloc() and write the data to that memory.
If I understand you correctly you don't need to allocate so much memory, but only 128 Bytes.
char buf[128];
while(/* condition */)
{
ret = fread(buf, sizeof buf, 1, fp_in);
encrypt(buf);
ret = fwrite(buf, sizeof buf, 1, fp_out);
}
isn't it possible to read bytes left in a file that is smaller than buffer size?
char * buffer = (char *)malloc(size);
FILE * fp = fopen(filename, "rb");
while(fread(buffer, size, 1, fp)){
// do something
}
Let's assume size is 4 and file size is 17 bytes. I thought fread can handle last operation as well even if bytes left in file is smaller than buffer size, but apparently it just terminates while loop without reading one last byte.
I tried to use lower system call read() but I couldn't read any byte for some reason.
What should I do if fread cannot handle last part of bytes that is smaller than buffer size?
Yep, turn your parameters around.
Instead of requesting one block of size bytes, you should request size blocks of 1 bytes. Then the function will return how many blocks (bytes) it was able to read:
int nread;
while( 0 < (nread = fread(buffer, 1, size, fp)) ) ...
try using "man fread"
it clearly mention following things which itself answers your question:
SYNOPSIS
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
DESCRIPTION
fread() copies, into an array pointed to by ptr, up to nitems items of
data from the named input stream, where an item of data is a sequence
of bytes (not necessarily terminated by a null byte) of length size.
fread() stops appending bytes if an end-of-file or error condition is
encountered while reading stream, or if nitems items have been read.
fread() leaves the file pointer in stream, if defined, pointing to the
byte following the last byte read if there is one.
The argument size is typically sizeof(*ptr) where the pseudo-function
sizeof specifies the length of an item pointed to by ptr.
RETURN VALUE
fread(), return the number of items read.If size or nitems is 0, no
characters are read or written and 0 is returned.
The value returned will be less than nitems only if a read error or
end-of-file is encountered. The ferror() or feof() functions must be
used to distinguish between an error condition and an end-of-file
condition.
I am trying to read a binary file in C 1 byte at a time and after searching the internet for hours I still can not get it to retrieve anything but garbage and/or a seg fault. Basically the binary file is in the format of a list that is 256 items long and each item is 1 byte (an unsigned int between 0 and 255). I am trying to use fseek and fread to jump to the "index" within the binary file and retrieve that value. The code that I have currently:
unsigned int buffer;
int index = 3; // any index value
size_t indexOffset = 256 * index;
fseek(file, indexOffset, SEEK_SET);
fread(&buffer, 256, 1, file);
printf("%d\n", buffer);
Right now this code is giving me random garbage numbers and seg faulting. Any tips as to how I can get this to work right?
Your confusing bytes with int. The common term for a byte is an unsigned char. Most bytes are 8-bits wide. If the data you are reading is 8 bits, you will need to read in 8 bits:
#define BUFFER_SIZE 256
unsigned char buffer[BUFFER_SIZE];
/* Read in 256 8-bit numbers into the buffer */
size_t bytes_read = 0;
bytes_read = fread(buffer, sizeof(unsigned char), BUFFER_SIZE, file_ptr);
// Note: sizeof(unsigned char) is for emphasis
The reason for reading all the data into memory is to keep the I/O flowing. There is an overhead associated with each input request, regardless of the quantity requested. Reading one byte at a time, or seeking to one position at a time is the worst case.
Here is an example of the overhead required for reading 1 byte:
Tell OS to read from the file.
OS searches to find the file location.
OS tells disk drive to power up.
OS waits for disk drive to get up to speed.
OS tells disk drive to position to the correct track and sector.
-->OS tells disk to read one byte and put into drive buffer.
OS fetches data from drive buffer.
Disk spins down to a stop.
OS returns 1 byte to your program.
In your program design, the above steps will be repeated 256 times. With everybody's suggestion, the line marked with "-->" will read 256 bytes. Thus the overhead is executed only once instead of 256 times to get the same quantity of data.
In your code you are trying to read 256 bytes to the address of one int. If you want to read one byte at a time, call fread(&buffer, 1, 1, file); (See fread).
But a simpler solution will be to declare an array of bytes, read it all together and process it after that.
unsigned char buffer; // note: 1 byte
fread(&buffer, 1, 1, file);
It is time to read mans I believe.
Couple of problems with the code as it stands.
The prototype for fread is:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
You've set the size to 256 (bytes) and the count to 1. That's fine, that means "read one lump of 256 bytes, shove it into the buffer".
However, your buffer is on the order of 2-8 bytes long (or, at least, vastly smaller than 256 bytes), so you have a buffer overrun. You probably want to use fred(&buffer, 1, 1, file).
Furthermore, you're writing byte data to an int pointer. This will work on one endian-ness (small-endian, in fact), so you'll be fine on Intel architecture and from that learn bad habits tha WILL come back and bite you, one of these days.
Try real hard to only write byte data into byte-organised storage, rather than into ints or floats.
You are trying to read 256 bytes into a 4-byte integer variable called "buffer". You are overwriting the next 252 bytes of other data.
It seems like buffer should either be unsigned char buffer[256]; or you should be doing fread(&buffer, 1, 1, f) and in that case buffer should be unsigned char buffer;.
Alternatively, if you just want a single character, you could just leave buffer as int (unsigned is not needed because C99 guarantees a reasonable minimum range for plain int) and simply say:
buffer = fgetc(f);