2

大きなコード内でファイルを開こうとしています。

ファイルを扱うときは、相対パスではなく絶対パスを使用する方が良いかもしれないと言われました。ただし、このコードは、ソースを別の場所 (/home/username、または /home/username/desktop/ など) に配置する可能性のあるさまざまな人によって使用されるため、相対パスを使用する方がよいと思います私の構成ファイルにアクセスします。これは、構成ファイルが cpp ファイルに関連してどこにあるかを知っているためです。

私の質問に関連するファイルの場所の簡単な要約は次のとおりです。

  • 読みたいファイルは /home/me/myproject/config/myfile.txt です

  • 私が読んでいるファイルは /home/me/myproject/src/myfile.cpp です

  • 「main」を含むファイルも /home/me/myproject/src/myfile.cpp です (この 1 つのファイルは巨大です)。

私はEclipseから実行可能ファイルを起動しています。eclipse は作業ディレクトリを「main」があるディレクトリ (/home/me/myproject/src/) に設定すると思います。

file.open() を呼び出そうとすると、作業ディレクトリ (getcwd()) が /home/me/myproject/ になっていることに困惑しています。どうやら作業ディレクトリは、main() と file.open() への呼び出しの間のコードによって変更されたようです。

私の質問は次のとおりです。プログラムの別の部分で変更できる場合、作業ディレクトリに依存するのは非常にエラーが発生しやすいようです。一方、他の開発者が通常ソースをどこに置いているのかわからない場合、構成パスがどこにあるのかを他にどのように知ることができますか?

4

2 に答える 2

2

私はEclipseから実行可能ファイルを起動しています。eclipse は作業ディレクトリを「main」があるディレクトリ (/home/me/myproject/src/) に設定すると思います。

よろしいですか?それはプロジェクト フォルダーのトップ レベル (つまり、"/home/eclipse/src" ではなく "/home/eclipse/myproject" のようなもの) であるように私には思えます。その理由は次のとおりです。

作業ディレクトリ (getcwd()) は /home/me/myproject/ になりました。

それは他の何かでしたか?明示的に何かを行った場合を除き、「プログラムの別の部分によって変更された」可能性はほとんどありません。

ソース コード実行可能ファイルの違いを理解しているかどうかはわかりません。ソース コード ファイルは「実行」されていません。実行可能ファイルにコンパイルされ、それが実行されます。Eclipse では、これらはデフォルトで src/ ディレクトリではなく、Release/ または Debug/ (見てください) に配置されます。(推定される) Eclipse がトップレベルのディレクトリを使用する理由は、それらのバージョン間の一貫性であるため、たとえば、それに関連する出力を行うことができます。

私の質問は次のとおりです。作業ディレクトリに依存するのは非常にエラーが発生しやすいようです。

それは間違いなく真実です。ユーザーのホーム ディレクトリへのパスを取得するには、OS 固有の方法があります。それを取得し、構成を保持する場所をドキュメントで指定する必要があります。ユーザーがそれを適切に実行できない場合、それはあなたのせいではありませんが、情報メッセージを発行します。「設定ファイルが見つかりません!」.

他の開発者が通常ソースをどこに置いているかわからない場合、構成パスがどこにあるのかを他にどのように知ることができますか?

実行可能ファイルを実行する必要がないため、「他の開発者」には必ずしもソースが含まれているとは限りません。

于 2012-04-23T13:43:12.637 に答える
-1

ファイルの場所を引数として受け入れることは常に良い考えです。そうすれば、あなたのソフトウェアを使用している人々は手間をかけずにさまざまな構成を試すことができます。

いつでもできることは、現在実行中のバイナリの場所を把握することです。直接的な方法が見つからない場合は、 と を組み合わせて使用​​しgetcwd()ますargv[0]。プロセス自体が変更されない場合、コマンドの実行後に作業ディレクトリは変更されません

次に、ファイル名を切り取り、構成ファイルの名前をパスに追加できます (base次の例では文字列に格納されています)。パスが絶対か相対かを判断し、それに応じて追加するコードを次に示します。boost_filesystemそれがクロスプラットフォームである必要があります:

#ifdef WITH_BOOST_FILESYSTEM
    boost::filesystem::path basepath(base), filepath(filename);
    if (!basepath.is_complete()) {
        basepath = filepath.remove_leaf() /= basepath;
        base = basepath.string();
    }
#elif __unix__
    if (base[0] != '/') {
        char *f = strdup(filename.c_str()), *d = dirname(f);
        base = string(d).append("/").append(base);
        free(f);
    }
#else
    std::cerr << "Warning: only absolute file paths accepted." << std::endl;
#endif
    base.append("/");
于 2012-04-23T13:45:29.600 に答える