目标和源文件不匹配-C

问题描述 投票:0回答:1

我一直试图找出测试仪失败的原因,它说目标文件和源文件不匹配。测试人员链接:https://github.com/ShiraWolf/hwOP.git输出要求和测试:它必须输出以下类型的消息之一(精确且区分大小写):

  • 无法打开源文件进行读取
  • 无法打开目标文件进行写入
  • 无法写入目标文件
  • 无法将缓冲区内容写入目标文件
  • 无法读取源文件
  • 无法关闭源文件
  • 无法关闭目标文件
  • 文件已成功复制到

或者如以上示例中所述,解析错误的各种参数之一。

我的代码:

    /*
 * ex1.c
 */

#include <sys/types.h>
#include <sys/stat.h>

#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAX_BUFFER_SIZE 65536
#define DESTINATION_FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH

extern int opterr, optind;

void exit_with_usage(const char *message) {
    fprintf (stderr, "%s\n", message);
    fprintf (stderr, "Usage:\n\tex1 [-f] BUFFER_SIZE SOURCE DEST\n");
    exit(EXIT_FAILURE);
}

void copy_file(const char *source_file, const char *dest_file, int buffer_size, int force_flag) {
    /*
     * Copy source_file content to dest_file, buffer_size bytes at a time.
     * If force_flag is true, then also overwrite dest_file. Otherwise print error, and exit.
     *
     * TODO:
     *  1. Open source_file for reading
     *  2. Open dest_file for writing (Hint: is force_flag true?)
     *  3. Loop reading from source and writing to the destination buffer_size bytes each time
     *  4. Close source_file and dest_file
     *
     *  ALWAYS check the return values of syscalls for errors!
     *  If an error was found, use perror(3) to print it with a message, and then exit(EXIT_FAILURE)
     */
    int c=0;
    int sourcef=0;
    int destf=0;
    sourcef=open(source_file,O_RDONLY);
    if(sourcef==-1){
        perror("Unable to open source file for reading");
        exit(EXIT_FAILURE);
    }
    destf = open(dest_file,O_WRONLY |O_CREAT|O_EXCL,00700);
    if(destf==-1){
        if(force_flag){
            destf= open(dest_file,O_WRONLY,00700);
            if(destf==-1){
                if(close(sourcef)==-1){
                    perror("couldn't close source file");
                    exit(EXIT_FAILURE);
                }
                perror("Unable to open destination for writing");
                exit(EXIT_FAILURE);
            }
        }else{
            perror("Unable to open destination for writing");
            exit(EXIT_FAILURE);
        }

    }
        char *buffer = malloc(sizeof(char)*buffer_size);
        while((c = read(sourcef,buffer,buffer_size))!= 0){
            if(c==-1){
                perror("couldn't read from source file");
                if(close(sourcef)==-1){
                    perror("couldn't close source file after reading has failed");
                    exit(EXIT_FAILURE);
                }
                if(close(destf)==-1){
                    perror("couldn't close dest file after reading has failed");
                    exit(EXIT_FAILURE);
                }
            exit(EXIT_FAILURE);
            }

            c = write(destf,buffer,buffer_size);
            if(c==-1){
                perror("couldn't write to source file");
                if(close(sourcef)==-1){
                    perror("couldn't close source file after writing has failed");
                    exit(EXIT_FAILURE);
                }
                if(close(destf)==-1){
                 perror("couldn't close dest file after writing has failed");
                 exit(EXIT_FAILURE);
               }
                exit(EXIT_FAILURE);
            }
        }
        free(buffer);

    if(close(sourcef)==-1){
        perror("couldn't close source file");
        exit(EXIT_FAILURE);
    }
    if(close(destf)==-1){
        perror("couldn't close dest file");
        exit(EXIT_FAILURE);
    }
    printf("File %s was copied to %s\n",source_file,dest_file );
    exit(EXIT_SUCCESS);
}

void parse_arguments(
        int argc, char **argv,
        char **source_file, char **dest_file, int *buffer_size, int *force_flag) {
    /*
     * parses command line arguments and set the arguments required for copy_file
     */
    int option_character;

    opterr = 0; /* Prevent getopt() from printing an error message to stderr */

    while ((option_character = getopt(argc, argv, "f")) != -1) {
        switch (option_character) {
        case 'f':
            *force_flag = 1;
            break;
        default:  /* '?' */
            exit_with_usage("Unknown option specified");
        }
    }

    if (argc - optind != 3) {
        exit_with_usage("Invalid number of arguments");
    } else {
        *source_file = argv[argc-2];
        *dest_file = argv[argc-1];
        *buffer_size = atoi(argv[argc-3]);

        if (strlen(*source_file) == 0 || strlen(*dest_file) == 0) {
            exit_with_usage("Invalid source / destination file name");
        } else if (*buffer_size < 1 || *buffer_size > MAX_BUFFER_SIZE) {
            exit_with_usage("Invalid buffer size");
        }
    }
}

int main(int argc, char **argv) {
    int force_flag = 0; /* force flag default: false */
    char *source_file = NULL;
    char *dest_file = NULL;
    int buffer_size = MAX_BUFFER_SIZE;

    parse_arguments(argc, argv, &source_file, &dest_file, &buffer_size, &force_flag);

    copy_file(source_file, dest_file, buffer_size, force_flag);

    return EXIT_SUCCESS;
}

有人可以看到我的错误在哪里吗?

c system-calls
1个回答
0
投票

c = write(destf, buffer, buffer_size);使用的大小不正确:您应写入c字节并将写入的计数存储到单独的变量nwritten中,并继续尝试写入更多字节,直到已写入c字节或write返回0-1

© www.soinside.com 2019 - 2024. All rights reserved.