Python 如何在C程序中避免错误的输入/输出文件名和错误的参数
我需要避免错误的输入/输出文件名以及无效参数。我也用过类似的东西,但实际上没有帮助:Python 如何在C程序中避免错误的输入/输出文件名和错误的参数,python,c,file,error-handling,Python,C,File,Error Handling,我需要避免错误的输入/输出文件名以及无效参数。我也用过类似的东西,但实际上没有帮助: while ((c = getopt(argc, argv, "i:o:")) != -1) { switch (c) { case 'i': inFile = strdup(optarg); break; case 'o':
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语言中避免错误文件名/错误文件路径以及无效参数处理的常用方法吗?假设“错误文件名”和“错误路径名”是指由于文件名或路径名有问题而无法打开的路径,那么,一般的做法是正确的:尝试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
作为您的retcode:
exit(errno)
这不是一个典型的操作,但是退出(-1)也不是。通常,您使用1
表示“一般故障”,使用-1表示“我退出,因为我捕获了信号1”
同时,还不清楚“坏文件名”和“坏路径名”是什么意思,但似乎所有这些都很重要:
- 路径的文件名部分太长<代码>错误号将为ENAMETOLOG
- 整个路径名太长<代码>错误号将为ENAMETOLOG
- 指定的目录或沿链指定的父目录之一不存在<代码>错误号将为
enoint
- 指定的目录或父目录之一不是目录<代码>错误号将为
ENOTDIR
- 路径名中包含无效字符。POSIX中没有这种情况,因此这只会发生在非POSIX平台上,如Windows,它通常不会定义调用C和POSIX函数返回的错误。(如果您确实想处理Windows错误,您可能希望使用
而不是CreateFile
等。)fopen
fopen(“ab\\?*:;\n\003”,“w+”)
,看看您得到了什么。然后你就知道应该在代码中添加什么了。假设“错误的文件名”和“错误的路径名”是指由于文件名或路径名有问题而无法打开的路径,那么你通常的做法是正确的:尝试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
作为您的retcode:
exit(errno)
这不是一个典型的操作,但是退出(-1)也不是。通常,您使用1
表示“一般故障”,使用-1表示“我退出,因为我捕获了信号1”
同时,还不清楚“坏文件名”和“坏路径名”是什么意思,但似乎所有这些都很重要:
- 路径的文件名部分太长<代码>错误号将为ENAMETOLOG
- 整个路径名太长<代码>错误号将为ENAMETOLOG
- 指定的目录或沿链指定的父目录之一不存在<代码>错误号将为
enoint
- 指定的目录或父目录之一不是目录<代码>错误号将为
ENOTDIR
- 路径名中包含无效字符。POSIX中没有这种情况,因此这只会发生在非POSIX平台上,如Windows,它通常不会定义调用C和POSIX函数返回的错误。(如果您确实想处理Windows错误,您可能希望使用
而不是CreateFile
等。)fopen
fopen(“ab\\?*:;\n\003”,“w+”)
,看看您得到了什么。然后,您就知道应该在代码中添加什么。在哪些方面“没有真正的帮助”?错误消息和返回值有什么问题?你想要什么不同?(尽管您可能希望记录errno
或strerror
。并且您可能希望返回一个正数,如1
,而不是-1
,因为这可能对某些人意味着您已退出,因为您发现了一个错误。)此外,“坏文件名”是什么?在大多数平台上,几乎任何字符都可以出现在POSIX上的文件名中,/
将被解释为路径分隔符而不是名称的一部分,\000
将被解释为文件名的结尾而不是其一部分,但其他任何字符都会出现,因此无需检查。一个主要的例外是Windows;如果您想要Windows特定的错误信息,您可能希望使用CreateFile
而不是fopen
,但您始终可以打印出errno
用于fopen的内容(“a\n*:\003”,“w+”)
,并自己找出答案。它在哪些方面“没有真正的帮助”?错误消息和返回值有什么问题?你想要什么不同?(尽管您可能希望登录