I've learned to write bytes from a file by reading the entire file into a character array and then writing them out to another file using fwrite. Of course, my teacher told me this is both wasteful and a file might not fit into memory, so I should use another method. What I want to do is write the exact copy of a file into my own file. How can I do this the better way? Thanks

Edited 6 Years Ago by RexxX: n/a

use fgets to read the source file one line at a time. this will take a small character array of some arbitrary length. say 80 or 120 characters. you could do it a lot smaller, but i don't see any reason why you would want to..

use fprintf to write those single lines, one line at a time, to your destination file.

these two functions are contained in a while loop that continues to execute as long as there are lines left to read in the source file.

while (fgets(buffer, 80, fileHandle1) != NULL)
    fprintf(filehandle2, "%s", buffer);

note, see where i hardcoded '80' as the size of the read. this is not a good practice, and would be better served using a #define'd constant, say MAX_BUFFER_READ, and the character buffer itself will need to be one character larger than this, to account for the terminating NULL character.

#define MAX_BUFFER_READ   80

char buffer[MAX_BUFFER_READ + 1];

while (fgets(buffer, MAX_BUFFER_READ, fileHandle1) != NULL)
    fprintf(filehandle2, "%s", buffer);

.

Edited 6 Years Ago by jephthah: n/a

Try looking at the macro BUFSIZ.

I found this about BUFSIZ

Macro: int BUFSIZ
The value of this macro is an integer constant expression that is good to use for the size argument to setvbuf. This value is guaranteed to be at least 256.

The value of BUFSIZ is chosen on each system so as to make stream I/O efficient. So it is a good idea to use BUFSIZ as the size for the buffer when you call setvbuf.

Actually, you can get an even better value to use for the buffer size by means of the fstat system call: it is found in the st_blksize field of the file attributes. See section 14.9.1 The meaning of the File Attributes.

Sometimes people also use BUFSIZ as the allocation size of buffers used for related purposes, such as strings used to receive a line of input with fgets (see section 12.8 Character Input). There is no particular reason to use BUFSIZ for this instead of any other integer, except that it might lead to doing I/O in chunks of an efficient size.

Edited 6 Years Ago by gerard4143: n/a

Stupid question, I just learned a little more about fread and write. is it legal to do

fwrite(FILE *a_ptr, file_size, 1,  FILE *b_ptr);

? That would be super convenient.

Edited 6 Years Ago by RexxX: n/a

no. not at all.

it doesnt get any more convenient than the example i handed you.

How would it handle a file pointer different from a char pointer? I can't use fgets because of binary files though, but fread and maybe 80 bytes will work fine.

EDIT - it has to be an exact number of bytes output...*sigh* so 80 fixed won't work.

Edited 6 Years Ago by RexxX: n/a

it doesnt work because file pointers and char pointers are two different things.

short answer: if they weren't different, they wouldn't have different names.

long answer: a char pointer is just a memory address that points to a location in memory of a group of characters. a file pointer is an integer "handle" that identifies a file stream and is associated with a structure that describes all the elements of that file stream.

Edited 6 Years Ago by jephthah: n/a

How would it handle a file pointer different from a char pointer? I can't use fgets because of binary files though, but fread and maybe 80 bytes will work fine.

EDIT - it has to be an exact number of bytes output...*sigh* so 80 fixed won't work.

okay, you're getting out in the weeds now.

fgets will read binary, you just have to open the file for a binary read FILE * fp = fopen(filename,"rb"); .

and fgets(buffer, numbytes, filestream) will read up to (numbytes - 1) or a newline or EOF character whichever comes first.

read the prototype for fgets


EDIT: you dont need to add 1 to the size of the buffer. fgets() will get one less bytes than the number of bytes argument, and tag the terminating NULL after that.


.

Edited 6 Years Ago by jephthah: n/a

I guess I just have to make up an algorithm so for the most part it prints out a fixed stream of bytes, until the last block of bytes, and then subtracts the null characters from the end so it doesn't print more bytes than the actual file. How does this sound?

You could try something like below:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char**argv)
{
	char mybuf[BUFSIZ];
	FILE *infd;
	FILE *outfd;

	if (!(infd = fopen("infile", "r")))
	{
		fputs("could not open infile!\n", stderr);
		exit(EXIT_FAILURE);
	}
	if (!(outfd = fopen("outfile", "w")))
	{
		fputs("could not open outfile!\n", stderr);
		exit(EXIT_FAILURE);
	}

	while ((fwrite(mybuf, 1, fread(mybuf, 1, BUFSIZ, infd), outfd))){}

	fclose(outfd);
	fclose(infd);
	exit(EXIT_SUCCESS);
}
Comments
we don't do people's homework.

I guess I just have to make up [a bunch of silliness] How does this sound?

sounds like you haven't even tried what i suggested. Go do what you want.

You could try something like below:

Gerard, you just typed up a fully-working code that uses practically the exact same method I've been saying all thread with the single exception that you use fwrite and fread instead of fgets and fprintf.

so how does this add to work ive been doing here, other than to "me too" a thread and give away full code to someones homework assignment?

Edited 3 Years Ago by Reverend Jim: Fixed formatting

Gerard, won't that code possibly print out bytes past the end of the file?

Jephthah, I'm asking you for a method, not for you to write my program.

Edited 6 Years Ago by RexxX: n/a

Gerard, won't that code possibly print out bytes past the end of the file?

no it doesnt. yes, his code works. do you even bother to try anything?

Jephthah, I'm asking you for a method, not for you to write my program.

I've given you a method. on further review, though, it does need a small change.

while (fgets(buffer, sizeof(buffer), fileHandle1) > 0)
fprintf(filehandle2, "%s", buffer);

oops. my bad.


.

Edited 6 Years Ago by jephthah: n/a

I didn't try it because by the looks of it, the code continually prints out a fixed stream of 80 bytes until the end of the file, so what's to prevent it from printing past the end of a file? Maybe you should stop ignoring what other people say, ie substituting in "blah blah" for my posts.

I didn't try it because by the looks of it, the code continually prints out a fixed stream of 80 bytes until the end of the file

No. It doesn't do that at all.

so what's to prevent it from printing past the end of a file?

Oh, just maybe the function prototype. Or that thing called the C standard library. Thing like that. However you prefer to think of it.


Maybe you should stop ignoring what other people say, ie substituting in "blah blah" for my posts.

i didn't substitute "blah blah". i summarized the context.

Now maybe YOU should stop ignoring the free help you get and first understand the functions -- or at least look them up -- before summarily dismissing them by what it "looks like"

:icon_rolleyes:


.

Edited 6 Years Ago by jephthah: n/a

I didn't try it because by the looks of it, the code continually prints out a fixed stream of 80 bytes until the end of the file, so what's to prevent it from printing past the end of a file? Maybe you should stop ignoring what other people say, ie substituting in "blah blah" for my posts.

You should read up on basic I/O. Here's a brief description of fread, fwrite return values from my manpages

RETURN VALUE
fread() and fwrite() return the number of items successfully read or
written (i.e., not the number of characters). If an error occurs, or
the end-of-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.

If you don't understand the above quote then get yourself a good intro book on C.

Edited 6 Years Ago by gerard4143: n/a

Just set up a buffer of x chars. Open the file for binary read.
Loop, reading x chars from the file. Write the characters.
Exit the loop when the read does not actually get x chars -- you've hit EOF.

This article has been dead for over six months. Start a new discussion instead.