スレッド: [cppll_novice:0756] プログラムが決まったファイルを読み込む場合。

スレッド

[cppll_novice:0756] プログラムが決まったファイルを読み込む場合。

[ | ▲ / | ]
Subject:
[cppll_novice:0756] プログラムが決まったファイルを読み込む場合。
From:
tetubou <tetubou@...>
Date:
Mon, 17 Jan 2005 21:24:32 +0900 (JST)
X-Mailer:
FreeML Web Mailer XP; SP2
Message-Id:
<5419759.1105964672032‐at‐www2.local.freeml.net>
いつもお世話になっている tetubou です。

ゲームなどの画像データのように、決まった名前の
ファイルをプログラムで読み込む場合のことです。
例えば、実行ファイルとデータファイルが同じディ
レクトリに存在する場合、

#include <fstream>

int main()
{
   std::ifstream data( "img.dat" );
   data.close();
   return 0;
}

のようにしてしまうと、実行ファイルとデータファイ
ルがあるディレクトリの外から実行ファイルを起動す
ると、データファイルが読み込めなくなってしまいま
す。
このような場合、普通はどのようにすれば解決できる
のでしょう?さんざん調べたのですが、根本的な解決
にはなりませんでした。

[cppll_novice:0757] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0757] Re: プログラムが決まったファイルを読み込む場合。
From:
恣意の <e3475@...>
Date:
Mon, 17 Jan 2005 21:51:46 +0900 (JST)
X-Mailer:
FreeML Web Mailer XP; SP2
Message-Id:
<2430624.1105966306038‐at‐www3.local.freeml.net>
In-Reply-To:
756
References:
756
恣意の@業務プログラマです。

> のようにしてしまうと、実行ファイルとデータファイ
> ルがあるディレクトリの外から実行ファイルを起動す
> ると、データファイルが読み込めなくなってしまいま
> す。

"int main()" の部分を
"int main(int argc, char* argv[])"
に変更して、argv[0]から実行exeのファイルパスを取得して何とかできませんか?

# 取得できるのはファイルフルパスなので
# 取得後は自分でファイル名を削除してくださいまし

# もしくはwin32(s)SDKを使用するならGetModuleFileName()と
# PathRemoveFileSpec()を併用して求めるのも手

[cppll_novice:0758] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0758] Re: プログラムが決まったファイルを読み込む場合。
From:
FUKUDA, Fumiki <epi-@...>
Date:
Tue, 18 Jan 2005 07:31:28 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2900.2180
Message-Id:
<001a01c4fce4$4ae65a90$0200a8c0@Fumiyo>
References:
756 757
επιστημηです。

> "int main()" の部分を
> "int main(int argc, char* argv[])"
> に変更して、argv[0]から実行exeのファイルパスを取得して何とかできませんか?

老婆心ながら──

argv[0] がロードモジュールのfull-pathになってる
ってのはOS依存なのでご注意くださいまし。

[cppll_novice:0760] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0760] Re: プログラムが決まったファイルを読み込む場合。
From:
tetubou <tetubou@...>
Date:
Tue, 18 Jan 2005 10:28:20 +0900 (JST)
X-Mailer:
FreeML Web Mailer XP; SP2
Message-Id:
<4113115.1106011700927‐at‐www2.local.freeml.net>
In-Reply-To:
758
References:
756 757 758
> επιστημηです。
>
> > "int main()" の部分を
> > "int main(int argc, char* argv[])"
> > に変更して、argv[0]から実行exeのファイルパスを取得して何とかできませ
んか?
>
> 老婆心ながら──
>
> argv[0] がロードモジュールのfull-pathになってる
> ってのはOS依存なのでご注意くださいまし。
>

επιστημηさんアドバイスありがとうございます。
επιστημηさんの仰る通り、私の環境では argv[0] はフルパスに
なっていませんでした。

自分はシェルスクリプトで対応する方法しか思いつきませんでした。
あと、当初の目的とは違ってしまうのですが実行ファイルのビルド
のときにインストールディレクトリを取得して makeファイルなどで
ソースファイルを書き換えるとか・・・・。

このような場合、επιστημηさんならばどのように処理
されるのでしょうか?

[cppll_novice:0761] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0761] Re: プログラムが決まったファイルを読み込む場合。
From:
FUKUDA, Fumiki <fukuda.fm@...>
Date:
Tue, 18 Jan 2005 10:48:56 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1409
Message-Id:
<001301c4fcff$e008a720$e87f340a@PCVA11JVHZH>
References:
756 757 758 760
επιστημηです。

> このような場合、επιστημηさんならばどのように処理
> されるのでしょうか?

うーん…己自身がどこにあるかを知る、可搬性のあるAPIが
見当たらないからには条件コンパイルでお茶を濁しますですねぇ。

std::string get_current_dir() {
#if うぃんどうず
 GetModuleFileName() でどーのこーの
 // VC++なら _getcwd() なんてのもあるか。
#elif うにくす
 えーと、どーしましょ? getcwd() とか使うのかしら?
 ふぉろーよろしく > だれぞ
#else
#error あんた誰?
#endif
}

とかなんとか。

[cppll_novice:0762] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0762] Re: プログラムが決まったファイルを読み込む場合。
From:
FUKUDA, Fumiki <fukuda.fm@...>
Date:
Tue, 18 Jan 2005 11:05:32 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1409
Message-Id:
<002901c4fd02$30b35ec0$e87f340a@PCVA11JVHZH>
References:
756 757 758 760 761
επιστημη@別解

> > このような場合、επιστημηさんならばどのように処理
> > されるのでしょうか?
>
> うーん…己自身がどこにあるかを知る、可搬性のあるAPIが
> 見当たらないからには条件コンパイルでお茶を濁しますですねぇ。

Boost使いましょうか。
boost::filesystem::current_path() なんてのがあります。
ドキュメントによれば、
UNIX系ならgetcwd, Winなら GetCurrentDirectoryAで実装されてるポ。

…欲しいのは現dirぢゃないのか。実行コードのあるdirか。うーむ…
UNIX系にそんなAPIあるっけ? ふぉろーよろしく > だれぞ

[cppll_novice:0765] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0765] Re: プログラムが決まったファイルを読み込む場合。
From:
Hisao Tsutsumi <tsutsumi@...>
Date:
Tue, 18 Jan 2005 11:38:22 +0900
X-Mailer:
Becky! ver. 2.12.01 [ja]
Message-Id:
<20050118112459.7292.TSUTSUMI‐at‐pf.highway.ne.jp>
In-Reply-To:
762
References:
761 762
堤です。

あやふやなので出すのを迷いましたがメールしちゃいます。

> …欲しいのは現dirぢゃないのか。実行コードのあるdirか。うーむ…
> UNIX系にそんなAPIあるっけ? ふぉろーよろしく > だれぞ

UNIXでGetModuleFileName()と同じ事を行う一般的な方法は無い
(はず)です。

Linuxだと
 readlink("/proc/self/exe", buf, bufsize);
みたいな感じで実行モジュールのフルパスを入手できたと思います。
これにdirnameを組み合わせれば何とかできるかも。

#手元にLinuxがないので自信なし……。
#誰かフォローをお願いします。m(_ _)m

ではでは。

--
Hisao Tsutsumi <tsutsumi@...>

[cppll_novice:0766] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0766] Re: プログラムが決まったファイルを読み込む場合。
From:
T.Sawamoto <sawamoto@...>
Date:
Tue, 18 Jan 2005 11:41:35 +0900
Message-Id:
<20050118113553.3BCE.SAWAMOTO‐at‐quasar.sakura.ne.jp>
In-Reply-To:
762
References:
761 762
さあもとです。

[cppll_novice:0762] FUKUDA, Fumiki wrote:
> UNIX系にそんなAPIあるっけ? ふぉろーよろしく > だれぞ

UNIXではないですが、Qtにはありますね。
(実はQt使ったことないけど(^^;))

QApplication::applicationDirPath
http://doc.trolltech.com/3.3/qapplication.html#applicationDirPath

ソースを呼んでみると、

Windowsのばやい → GetModuleFileName
MacOSのばやい → qAppFileName
それ以外 → argv[0] / カレントディレクトリ / $PATHから検索

となってます。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
 へ  へ    さあもと
 の  の    E-Mail : sawamoto@...
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

[cppll_novice:0767] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0767] Re: プログラムが決まったファイルを読み込む場合。
From:
Masamichi Takatsu <taka2@...>
Date:
Tue, 18 Jan 2005 11:45:22 +0900
X-Mailer:
mnews [version 1.22PL6T1(IMAP4,UNICODE)] 2003-12/12(Fri)
Message-Id:
<050118114522.M0100468‐at‐XP.doga.jp>
In-Reply-To:
762
たかつです。

> …欲しいのは現dirぢゃないのか。実行コードのあるdirか。うーむ…
> UNIX系にそんなAPIあるっけ? ふぉろーよろしく > だれぞ

それを知る方法は UNIX にはありません。

で、argv[0] の方も意味がある文字列になっているとは限らないのですが、
大抵の場合、 argv[0] にはシェルのコマンドラインに指定した文字列が
そのまま入っているものですから、実行ファイルのあるディレクトリを
知るには

・フルパス(/で始まる)の場合は、そのまま
・相対パスの場合(/が含まれる)は、カレントディレクトリと連結
・そうでなければ、環境変数 PATH から探索

といった処理を行うのが順当な手段かと思います。

もっとも、UNIX の場合は、プログラムと同じディレクトリにファイルを置く
なんていうのは邪道で、普通は
       /usr/local/プログラム名/…
とか
       /usr/local/etc/プログラム名/…
にハードコートするものだと思います。

詳しくは
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_2.html#SEC23
こちらを読んでください。

PROJECT TEAM DoGA 高津正道                            taka2@...
                                                  TBD00456@...
                    PROJECT TEAM DoGAのホームページ → http://doga.jp/
1月18日(火) 今日のマーフィーの法則        [ウインフィールドの「行く先の道順」の金言]
道を教える人が「簡単にわかりますよ」と言えば言うほど、迷子になりやすい。

[cppll_novice:0768] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0768] Re: プログラムが決まったファイルを読み込む場合。
From:
OKI miyuki <oki@...>
Date:
Tue, 18 Jan 2005 11:53:06 +0900
X-Mailer:
Microsoft Outlook Express 6.00.2800.1478
Message-Id:
<008c01c4fd08$d5d183e0$0300030a‐at‐hunes.local>
References:
756 757 758 760 761 762
oki です。

>
> …欲しいのは現dirぢゃないのか。実行コードのあるdirか。うーむ…
> UNIX系にそんなAPIあるっけ? ふぉろーよろしく > だれぞ
>

 わかんないすが、

1.単純に環境変数に特定ディレクトリ
  を設定しておいて、getenv で読む

2.argv[1] に特定ディレクトリを指定するように
  作成しておき、シェルスクリプトを実行する形で
  吸収する。

なんてのは、どうでしょ?

[cppll_novice:0759] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0759] Re: プログラムが決まったファイルを読み込む場合。
From:
tetubou <tetubou@...>
Date:
Tue, 18 Jan 2005 10:20:20 +0900 (JST)
X-Mailer:
FreeML Web Mailer XP; SP2
Message-Id:
<3261581.1106011220827‐at‐www2.local.freeml.net>
In-Reply-To:
757
References:
756 757
> 恣意の@業務プログラマです。
>
> > のようにしてしまうと、実行ファイルとデータファイ
> > ルがあるディレクトリの外から実行ファイルを起動す
> > ると、データファイルが読み込めなくなってしまいま
> > す。
>
> "int main()" の部分を
> "int main(int argc, char* argv[])"
> に変更して、argv[0]から実行exeのファイルパスを取得して何とかできませんか?
>
> # 取得できるのはファイルフルパスなので
> # 取得後は自分でファイル名を削除してくださいまし
>
> # もしくはwin32(s)SDKを使用するならGetModuleFileName()と
> # PathRemoveFileSpec()を併用して求めるのも手
>

おはようございます。返信ありがとうございます。
私は、argv[0]が指す文字列はコマンドラインで実行ファイル名として
タイプした文字列そのものだという理解でした。
試しに私の環境でやってみましたが、残念ながら私のイメージ通りの
結果になってしまいました。

具体的には、パスの通ったディレクトリに実行ファイルのシンボリック
リンクをインストールする場合ですが、argv[0]はシンボリックリンク
名を指していました。

[cppll_novice:0764] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0764] Re: プログラムが決まったファイルを読み込む場合。
From:
恣意の <e3475@...>
Date:
Tue, 18 Jan 2005 11:34:02 +0900 (JST)
X-Mailer:
FreeML Web Mailer XP; SP2
Message-Id:
<861769.1106015642497‐at‐www3.local.freeml.net>
In-Reply-To:
759
References:
756 757 759
恣意のです。

> > "int main()" の部分を
> > "int main(int argc, char* argv[])"
>
> おはようございます。返信ありがとうございます。
> 私は、argv[0]が指す文字列はコマンドラインで実行ファイル名として
> タイプした文字列そのものだという理解でした。
> 試しに私の環境でやってみましたが、残念ながら私のイメージ通りの
> 結果になってしまいました。

# うわ、知識誤認が露呈した

そすると、モジュールそのものを"モジュールディレクトリを基準に動作"する
ものから"指定された任意ディレクトリパスを基準に動作"するものとみなして、
コマンドラインにて"基準ディレクトリパス"を指定してもらうように割り切っ
て動作させるしかないのかしらん・・・

# 解決になってない・・・
# もっと精進しないとなぁ

[cppll_novice:0778] Re: プログラムが決まったファイルを読み込む場合。

[ | / | ]
Subject:
[cppll_novice:0778] Re: プログラムが決まったファイルを読み込む場合。
From:
tetubou <tetubou@...>
Date:
Wed, 19 Jan 2005 08:41:54 +0900 (JST)
X-Mailer:
FreeML Web Mailer XP; SP2
Message-Id:
<4358035.1106091714503‐at‐www2.local.freeml.net>
In-Reply-To:
759
References:
756 757 759
みなさん沢山の返信ありがとうございます。
やはり、環境依存するかビルドの際に対応するという
方法になってしまうんですね。

[cppll_novice:0763] Re: プログラムが決まったファイルを読み込む場合。

[ | / ▼ | ]
Subject:
[cppll_novice:0763] Re: プログラムが決まったファイルを読み込む場合。
From:
Lichtenstein <lichtenstein@...>
Date:
Tue, 18 Jan 2005 11:25:30 +0900
X-Mailer:
EdMax Ver3.05 (On Trial)
Message-Id:
 
In-Reply-To:
756
References:
756
こんにちは。Lihctenです。

↓の記事を参考に、tetubouさんにとって最適な方法を選んでみてはどうでしょうか?
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_2.html#SEC23

個人的には、OSの機能に依存するのが最も単純な解で、間違いが無いと思っています。

以上

tetubou <tetubou@...> wrote:

> いつもお世話になっている tetubou です。
>
> ゲームなどの画像データのように、決まった名前の
> ファイルをプログラムで読み込む場合のことです。
> 例えば、実行ファイルとデータファイルが同じディ
> レクトリに存在する場合、
>
> #include <fstream>
>
> int main()
> {
>     std::ifstream data( "img.dat" );
>     data.close();
>     return 0;
> }
>
> のようにしてしまうと、実行ファイルとデータファイ
> ルがあるディレクトリの外から実行ファイルを起動す
> ると、データファイルが読み込めなくなってしまいま
> す。
> このような場合、普通はどのようにすれば解決できる
> のでしょう?さんざん調べたのですが、根本的な解決
> にはなりませんでした。
>
>
> --[PR]------------------------------------------------------------------
>          ★☆★  「懸賞侍」見参!!  ★☆★
>        侍ゲームで楽しく遊んで、豪華賞品を当てちゃおう!
>             この戦国懸賞時代を制するのは君だ!
>           さあ、バッサバッサと当ててしまえ!!!
>       http://www.kenshosamurai.com/regist.html?aid=frml041227
> ------------------------------------------------------------------[PR]--
> ■GMO GROUP■ Global Media Online  www.gmo.jp
>
>
>

Navigation

検索

[検索ヘルプ]

Maintener: Tietew <www.tietew.jp>
Powered by Ruby on Rails, Mongrel, PostgreSQL, and Hyper Estraier.
click here