我一直试图找出测试仪失败的原因,它说目标文件和源文件不匹配。测试人员链接: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 = write(destf, buffer, buffer_size);
使用的大小不正确:您应写入c
字节并将写入的计数存储到单独的变量nwritten
中,并继续尝试写入更多字节,直到已写入c
字节或write
返回0
或-1
。