为什么这个函数没有复制输入文件?

时间:2018-06-14 10:01:13

标签: c file-io

我刚刚开始进入文件I / O并且正在尝试构建一个只将文件复制到目标的函数。

但是,该程序编译时会创建一个空文件,并且不会复制任何内容。有什么建议吗?

#include <stdio.h>

int copy_file(char FileSource[], char FileDestination[]) {
    char content;

    FILE *inputf = fopen(FileSource, "r");
    FILE *outputf = fopen(FileDestination, "w");

    if (inputf == NULL)
        ;
    printf("Error: File could not be read \n");
    return;

    while ((content = getc(inputf)) != EOF) putc(content, inputf);

    fclose(outputf);
    fclose(inputf);
    printf("Your file was successfully copied");

    return 0;
}


int main() {
    char inputname[100];
    char outputname[100];

    printf("Please enter input file name: \n");
    scanf("%s", &inputname);
    printf("Please write output file name: \n");
    scanf("%s", &outputname);

    copy_file(inputname, outputname);

    return 0;
}

5 个答案:

答案 0 :(得分:1)

您提到的代码中存在很少的错误。这两个下面的陈述

scanf("%s", &inputname);
scanf("%s", &outputname);

错误为inputnameoutputname是char数组和数组名称本身地址,因此您无需将&inputname提供给scanf()。例如

scanf("%s",inputname);
scanf("%s",outputname);

;声明末尾的if也未达到您预期的正确目的。

这个

if(inputf == NULL);

应该是

if(inputf == NULL){ 
     /*error handling */ 
}

正如其他人所指出的那样,getc()会返回int而非char。来自getc()

的手册页
  

int getc(FILE *stream);

这个

 putc(content, inputf);

更改为

putc(content, outputf); /* write the data into outputf */

答案 1 :(得分:0)

你的专栏:

putc(content, inputf);

需要改为

putc(content, outputf);

答案 2 :(得分:0)

此代码存在很多问题:

if(inputf == NULL); 
    printf("Error: File could not be read \n");
    return;

相当于

if(inputf == NULL)
{
    ;
} 
printf("Error: File could not be read \n");
return;

你有一个迷路的;终止了你if的陈述,而且空格对C来说并不重要。

因此,您的if语句不执行任何操作,并且您的代码将始终发出&#34;错误:无法读取文件&#34;消息并返回而不做任何其他事情。

你可能想要什么:

if(inputf == NULL)
{
    printf("Error: File could not be read \n");
    return;
}

这是为什么很多C程序员始终if语句之后使用大括号的完美示例。 始终

答案 3 :(得分:0)

您的代码中存在多个问题:

  • content必须声明为intgetc()返回int,其中包含从文件中读取的字节值或特殊负值EOF在文件的末尾。将其存储到char变量会丢失信息,导致EOF的测试不明确(如果char已签名)或始终为假(如果char默认为无符号)。
  • 您应该将outputf传递给putc
  • 如果copy_file无法打开任何文件,您应该从fopen函数返回。
  • 您应该传递要为文件名读取的最大字符数
  • 您应该检查scanf()的返回值,以避免无效输入时出现未定义的行为。

以下是更正后的版本:

#include <stdio.h>

int copy_file(const char *FileSource, const char *FileDestination) {
    int content;
    FILE *inputf, *outputf;

    if ((inputf = fopen(FileSource, "r")) == NULL) {
        printf("Error: cannot open input file %s\n", FileSource);
        return -1;
    }
    if ((outputf = fopen(FileDestination, "w")) == NULL) {
        printf("Error: cannot open output file %s\n", FileDestination);
        fclose(inputf);
        return -1;
    }

    while ((content = getc(inputf)) != EOF)
        putc(content, inputf);

    fclose(outputf);
    fclose(inputf);
    printf("Your file was successfully copied");

    return 0;
}

int main() {
    char inputname[100];
    char outputname[100];

    printf("Please enter input file name: \n");
    if (scanf("%99s", inputname) != 1)
        return 1;
    printf("Please write output file name: \n");
    if (scanf("%99s", &outputname) != 1)
        return 1;

    copy_file(inputname, outputname);
    return 0;
}

答案 4 :(得分:0)

使用sendfile()更简单有效地复制文件。您可以通过 man sendfile 查看有关sendfile()的更多详细信息。

#include <stdio.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        printf("Usage: %s <srcfile> <dst_file>\n", argv[0]);
        return 1;
    }

    char *src_file = argv[1];
    char *dst_file = argv[2];
    int src;
    int dst;
    ssize_t size;
    struct stat stat_buf;

    if ((src = open(src_file, O_RDONLY)) < 0)
    {
        printf("Can not open %s\n", src_file);
        return -1;
    }

    if (fstat(src, &stat_buf) < 0)
    {
        printf("Can stat %s\n", src_file);
        close(src);
        return -2;
    }

    if ((dst = open(dst_file, O_CREAT|O_WRONLY, stat_buf.st_mode)) < 0)
    {
        printf("Can not open %s\n", dst_file);
        return -1;
    }

    if ((size = sendfile(dst, src, NULL, stat_buf.st_size)) < 0)
    {
        printf("Fail to copy file, size: %ld\n", size);
    }
    else
    {
        printf("Success, size: %ld\n", size);
    }

    close(src);
    close(dst);
    return 0;
}