C二进制I / O程序问题

时间:2016-03-01 00:35:29

标签: c file-io

我目前正在尝试创建一个程序来操作从命令行参数解析的二进制文件。程序插入二进制文件(input.bin),在输出文件的开头插入unsigned int后将其复制到另一个文件(output.bin)。命令如下:

$./padder input.bin output.bin 50

然而我的输出给了我:

Source successfully written to destination after padding by 53

我遇到的第一个问题是53不是我传入pad(insert)的int。我的第二个问题是,在将我的input.bin文件和我的output.bin文件重新输入后,它们是相似的,但不完全是我想要的。

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

有人能给我一些见解吗?我是File I / O的新手,相当新,但在C中没有经验丰富。感谢任何帮助

源代码:

#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;
}

1 个答案:

答案 0 :(得分:2)

在输出文件的开头插入unsigned int 是什么意思?

您的代码当前复制文件的开头但写入的内容是读取的4倍,可能会读取buff的末尾并尝试用未指定的数据覆盖开头,通过读取来调用未定义的行为记忆远远超出pad的结尾。

如果要在命令行中指定的整数值的小端二进制表示形式插入4个字节作为数字字符串,则在文件副本的开头,您可以这样修改程序: / p>

#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;
}