我需要避免错误的输入/输出文件名以及无效的参数。我也使用过这样的东西,但它并没有真正起作用:
while ((c = getopt(argc, argv, "i:o:")) != -1) {
switch (c) {
case 'i':
inFile = strdup(optarg);
break;
case 'o':
outFile = strdup(optarg);
break;
default:
//usage(argv[0]);
break;
}
}
if ((ptr1 = fopen(inFile, "r+")) == NULL) {
fprintf(stderr, "Error: cannot open file %s\n", inFile);
exit(-1);
}
if ((ptr = fopen(outFile, "w+")) == NULL) {
fprintf(stderr, "Error: cannot open file %s\n", outFile);
exit(-1);
}
测试我的程序的python程序如下:
class Arg2(Test):
name = "arg2"
description = "bad arguments"
timeout = 5
def run(self):
self.runexe(["fastsort", "a", "b", "c", "d"],
stderr = usage_error, status = 1)
self.done()
class Badin(Test):
name = "badin"
description = "bad input file"
timeout = 5
def run(self):
invalid = mktemp(prefix='/invalid/path/')
self.runexe(["fastsort", "-i", invalid, "-o", "outfile"],
stderr = "Error: Cannot open file {0}\n".format(invalid), status = 1)
self.done()
class Badout(Test):
name = "badout"
description = "bad output file"
timeout = 5
def run(self):
infile = self.project_path + "/infile"
# create a valid (empty) input file
open(infile, "a").close()
invalid = mktemp(prefix='/invalid/path/')
self.runexe(["fastsort", "-i", infile, "-o", invalid],
stderr = "Error: Cannot open file {0}\n".format(invalid), status = 1)
self.done()
您能否给我一些提示和代码片段,以避免错误的文件名/错误的文件路径以及C中的无效参数处理?
答案 0 :(得分:1)
假设“错误的文件名”和“错误的路径名”意味着您无法打开的路径,因为文件名或路径名出错,那么您正在进行此操作的一般方法是正确的:尝试fopen
,并在事后报告错误,而不是试图猜测它是否会起作用。
您缺少的是检查失败时errno
。而不是这个通用错误:
fprintf(stderr, "Error: cannot open file %s\n", inFile);
...使用errno
,strerror
或perror
打印出特定内容:
fprintf(stderr, "Error: cannot open file ");
perror(inFile);
然后你会得到类似的东西:
Error: cannot open file foo/bar: No such file or directory.
如果您想以编程方式区分错误,请检查errno
:
if (errno == ENOENT) {
/* The directory, or one of its parents, doesn't exist, so handle that */
} else {
/* whatever */
}
另一方面,如果您想将信息传递回调用程序,只需返回errno
作为您的重新编码:
exit(errno)
这不是一个典型的事情 - 但是exit(-1)
也不是。通常你使用1
表示“一般失败”,-1表示“我退出因为我抓住了信号1”。
与此同时,目前尚不清楚“坏文件名”和“坏路径名”是什么意思,但似乎所有这些都算得上:
errno
将是ENAMETOOLONG。errno
将是ENAMETOOLONG。errno
将为ENOENT
。errno
将为ENOTDIR
。CreateFile
而不是fopen
等。)如果你需要在Windows或其他平台上处理最后一个案例,最好的办法是测试它:尝试fopen("a b \\?*:; \n \003", "w+")
并看看你得到了什么。然后你就会知道你的代码中要放什么。