1

不正な入出力ファイル名や無効な引数を避ける必要があります。私もこのようなものを使用しましたが、実際には役に立ちません:

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 での無効な引数処理を回避する通常の方法のヒントとコード スニペットを教えてください。

4

1 に答える 1

1

「悪いファイル名」と「悪いパス名」とは、ファイル名またはパス名に何か問題があるために開くことができないパスを意味すると仮定すると、これについての一般的な方法は正しいですfopen:動作するかどうかを推測しようとするのではなく、事後にエラーを報告します。

あなたが見逃しているのはerrno、失敗時のチェックです。この一般的なエラーの代わりに:

fprintf(stderr, "Error: cannot open file %s\n", inFile);

errnostrerror、またはを使用して特定のものを出力し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 */
}

一方、情報を呼び出し元のプログラムに戻したい場合は、errnoretcode として返すだけです。

exit(errno)

これは一般的なことではありませんが、exit(-1)そうでもありません。通常1、「一般的な失敗」に対して使用し、「シグナル 1 をキャッチしたため終了しました」に対して -1 を使用します。


一方、「悪いファイル名」と「悪いパス名」が何を意味するのかは明確ではありませんが、これらすべてがカウントされるようです:

  • パスのファイル名部分が長すぎます。errnoエナメトゥーロンになります。
  • パス名全体が長すぎます。errnoエナメトゥーロンになります。
  • 指定されたディレクトリ、またはチェーンに沿って指定された親の 1 つが存在しません。errnoとなりますENOENT
  • 指定されたディレクトリ、または親の 1 つがディレクトリではありません。errnoとなりますENOTDIR
  • パス名に無効な文字が含まれています。POSIX にはそのようなことはありません。したがって、これは Windows などの非 POSIX プラットフォームでのみ発生します。一般に、C および POSIX 関数の呼び出しから返されるエラーが定義されていません。(Windows のエラーを本当に処理したい場合は、 などCreateFileではなく、おそらく使用したいでしょうfopen。)

Windows またはその他のプラットフォームで最後のケースに対処する必要がある場合、最善の方法はそれをテストすることfopen("a b \\?*:; \n \003", "w+")です。次に、コードに何を入れるかがわかります。

于 2013-09-16T22:49:50.007 に答える