Reputation: 7320
I was wondering.. how do you read bytes one at a time from a binary file? As an example, I'd like to read bytes one at a time from some binary file and then write those exact bytes to some output file (basically a very basic implementation of the cp
command). My current C code looks like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char**argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
return 1;
}
FILE *outfile;
outfile = fopen(argv[1], "w");
unsigned char c;
char temp;
int tracker = 0;
// Use temp because unsigned char will never be EOF
while ((temp = getchar()) != EOF) {
c = (unsigned char) temp;
fprintf(outfile, "%c", c);
}
fclose(outfile);
return 0;
}
I run the program like this: ./main output.au < sample.au
(.au is an audio file)
However, all I get in the output.au
file is a bunch of "^@" repeated over and over. I can play the sample.au
audio file fine, but not the output.au
. I've also (somewhat pointlessly) done a diff
on the two files, and as expected they come out differently.
Help? Thanks! -kstruct
UPDATE Thanks for the reply everyone.. my code now looks like:
outfile = fopen(argv[1], "wb");
int c;
while ((c = getchar()) != EOF) {
fprintf(outfile, "%c", c);
}
Upvotes: 2
Views: 3093
Reputation: 3564
There are several things that need to get fixed:
1) Reopen STDIN as binary. freopen(NULL, "rb", stdin);
2) Open the outfile as: fopen(argv[1], "wb");
3) temp needs to be of type int.
Upvotes: 2
Reputation: 108938
getchar()
returns an int
.
You assign that int
to a variable of type char
thereby losing information. Don't do that.
Declare temp
as int, and go get rid of the cast.
Upvotes: 7
Reputation: 43280
make the following corrections:
- outfile = fopen(argv[1], "w");
+ outfile = fopen(argv[1], "wb");
- c = (unsigned char) temp;
+ c = (unsigned char) (char) temp;
Upvotes: 0