Reputation: 131
I'm currently trying to make a program that manipulates a binary file parsed from command line arguments. The program intakes a binary file (input.bin) , copies it to another file (output.bin) after inserting an unsigned int at the beginning of the output file. The command goes as such:
$./padder input.bin output.bin 50
However my output gives me:
Source successfully written to destination after padding by 53
The first issue I'm having is that 53 is not the int I passed in to pad (insert). The second issue I have is that after hexdumping both my input.bin file and my output.bin file, they are similar but not exactly what I want.
Hexdump input.bin:
0000000 3231 3433 3635 3837 3039 000a
000000b
Hexdump output.bin:
0000000 3231 3433 3635 3837 3039 000a 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
000002c
Could anyone give me some insight? I'm new to File I/O and fairly new but not seasoned in C. Any help is appreciated
source code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc, char *argv[]){
if(argc != 4){
printf("ERROR: INCORRECT AMOUNT OF ARGUMENTS!!!\n");
} else {
FILE *input = fopen(argv[1], "rb");
if(input == NULL){
perror("INPUT FILE OPEN");
exit(EXIT_FAILURE);
}
FILE *dest = fopen(argv[2], "wb");
if(dest == NULL){
perror("DEST FILE OPEN");
exit(EXIT_FAILURE);
}
unsigned int *pad_val = (unsigned int *)argv[3];
unsigned char *pad = (unsigned char *) pad_val;
size_t n, m;
unsigned char buff[4096];
do{
n = fread(buff, 1, sizeof buff, input);
if(n){
m = fwrite(buff, 4, n, dest);
rewind(dest);
m = fwrite(&pad, 1, n, dest);
} else {
m = 0;
}
} while((n > 0) && (n == m));
if(m){
perror("copy");
}
printf("Source successfully written to destination after padding by %u\n", *pad);
fclose(input);
fclose(dest);
}
return 0;
}
Upvotes: 0
Views: 90
Reputation: 144780
What do you mean precisely by inserting an unsigned int at the beginning of the output file?
Your code currently copies the beginning of the file but write 4 times as many bytes as it reads, potentially reading past the end of buff
and attempts to overwrite the beginning with unspecified data, invoking undefined behavior by reading from memory well beyond the end of pad
.
If you want to insert 4 bytes with the little endian binary representation of an integer value specified on the command line as a string of digits, at the beginning of a copy of the file, you can modify your program this way:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
if (argc != 4) {
printf("ERROR: INCORRECT AMOUNT OF ARGUMENTS!!!\n");
return 1;
}
FILE *input = fopen(argv[1], "rb");
if (input == NULL) {
perror("INPUT FILE OPEN");
exit(EXIT_FAILURE);
}
FILE *dest = fopen(argv[2], "wb");
if (dest == NULL) {
perror("DEST FILE OPEN");
exit(EXIT_FAILURE);
}
unsigned int pad_val = strtoul(argv[3], NULL, 0);
fputc((pad_val >> 0) & 255, dest);
fputc((pad_val >> 8) & 255, dest);
fputc((pad_val >> 16) & 255, dest);
fputc((pad_val >> 24) & 255, dest);
size_t n;
unsigned char buff[4096];
while ((n = fread(buff, 1, sizeof buff, input)) > 0) {
if (fwrite(buff, 1, n, dest) != n) {
perror("fwrite");
break;
}
}
fclose(input);
if (fclose(dest)) {
perror("fclose");
} else {
printf("Source successfully written to destination after padding by %u\n", pad_val);
}
return 0;
}
Upvotes: 2