目标文件和源文件不匹配 - C
Destination and Source file don't match - C
我一直在试图找出我的测试仪失败的原因,它说目标文件和源文件不匹配。 link 测试人员: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
并继续尝试写入更多字节直到 [=已写入 12=] 个字节或 write
return 0
或 -1
.
这是复制循环的修改版本:
while ((c = read(sourcef, buffer, buffer_size)) != 0) {
if (c == -1) {
perror("Unable to read from source file");
if (close(sourcef) == -1) {
perror("Unable to close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("Unable to close destination file");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
int towrite = c;
int pos = 0;
while (towrite > 0) {
int nwritten = write(destf, buffer + pos, towrite);
if (nwritten <= 0) {
perror("Unable to write to destination file");
if (close(sourcef) == -1) {
perror("Unable to close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("Unable to close destination file");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
pos += nwritten;
towrite -= nwritten;
}
}
另请注意,其他错误消息与规范不同。
我一直在试图找出我的测试仪失败的原因,它说目标文件和源文件不匹配。 link 测试人员: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
并继续尝试写入更多字节直到 [=已写入 12=] 个字节或 write
return 0
或 -1
.
这是复制循环的修改版本:
while ((c = read(sourcef, buffer, buffer_size)) != 0) {
if (c == -1) {
perror("Unable to read from source file");
if (close(sourcef) == -1) {
perror("Unable to close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("Unable to close destination file");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
int towrite = c;
int pos = 0;
while (towrite > 0) {
int nwritten = write(destf, buffer + pos, towrite);
if (nwritten <= 0) {
perror("Unable to write to destination file");
if (close(sourcef) == -1) {
perror("Unable to close source file");
exit(EXIT_FAILURE);
}
if (close(destf) == -1) {
perror("Unable to close destination file");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
pos += nwritten;
towrite -= nwritten;
}
}
另请注意,其他错误消息与规范不同。