- ベストアンサー
ファイルがオープンできない
現在コマンドライン引数を利用した、Drag&Dropで入力されたバイナリファイルをテキストファイルに出力するプログラムをCで作成しています。 その過程で、Drag&Dropされたファイル以外にもテキストファイル(option.txt)を読み込みたいのですが、どうしてもそのファイルをオープンすることができません。 次は問題の部分だけを抜き出したソースです。 #include <stdio.h> int main(int argc,char *argv[]) { FILE *s; s=fopen("option.txt","r"); if( !s ){ printf("Error: cannot open file(option.txt)\n"); } else printf("OK!\n"); if(argc == 2) printf("%s\n",argv[1]); else if(argc ==1) printf("No Drag&Drop File\n"); return 0; } Drag&Dropしない時(作成された実行ファイルをダブルクリックで起動する時)は OK! No Drag&Drop File となり、問題のoption.txtのファイルは開けているのですが、適当なバイナリファイル(7.chn)をDrag&Dropすると Error: cannot open file(option.txt) C:\Documents and Settings\[ユーザー名]\デスクトップ\Program\7.chn と、先ほどまで開けていたoption.txtのテキストファイルが急に開けなくなってしまいました。 どうにも原因・解決策が分かりませんでしたので、お聞きしたくこちらに書き込みをさせてもらいました。 どなたか分かる方いらっしゃいましたらよろしくお願いします。
- みんなの回答 (15)
- 専門家の回答
質問者が選んだベストアンサー
#11回答者です。 >よって、argv[0]でフルパスが取れるか否かは処理系次第です。 #7の回答・補足から処理系は判明しています。 WindowsXP Borland C++ Compiler 5.5 同じ環境で動作確認しましたので、問題ないと思いますが、違うバージョンのWindowsで動かす予定があれば念のため動作確認した方が良いかも知れませんね。 ついでに、とことん手抜きのプログラム書くと・・・ 実行ファイルのファイル名の長さは決まっていると思うので、こんな感じで。 #include <stdio.h> #include <string.h> #define EXEFILE_LEN 7 //実行ファイルのファイル名の長さ void main(int argc,char *argv[]) { char str[1024]; //エラー処理してないので多めに strcpy(str,argv[0]); str[strlen(argv[0])-EXEFILE_LEN] = '\0'; //ファイル名の前で切る strcat(str,"option.txt"); puts(str); {char c = getchar();} }
その他の回答 (14)
- Kyo99
- ベストアンサー率12% (1/8)
試してないので自信ないのですが"option.txt"を絶対パス("c:\\option.txt"など)で書いてみるのはどうでしょうか。(Drag&Dropで実行した場合、プログラムはDrag元で実行されたような気がします。)
お礼
すみません、お礼を書くのを忘れてしまいました! Dragもとのディレクトリでプログラムが実行されるとしたら、別のディレクトリからDragした場合を考えると、絶対パスのほうがいいのかもしれないですね。 どうも、ありがとうございました。
補足
絶対パスにするとちゃんと開くことができました。 しかし、Drag元とDrag先は実行ファイルやCのソースファイルがあるディレクトリにあり、そのディレクトリにoption.txtもありますので、カレントディレクトリにoption.txtもあるはずと思うのですが、この相対パスの指定方法で何が問題なのかが疑問には残るところではあります。
- MrBan
- ベストアンサー率53% (331/615)
多分、「カレントディレクトリ」が違うせいかと思われます。 Drag&Drop時はカレントが、 C:\Documents and Settings\[ユーザー名]\デスクトップ\Program\ になっているので、単に"option.txt"とかくと、 C:\Documents and Settings\[ユーザー名]\デスクトップ\Program\option.txt を開こうとします。で、これが見つからずにエラーになってます。 絶対パスにするなり、GetModuleFileName等の利用を検討してください。
補足
いえ、そのoption.txtがあるディレクトリがカレントディレクトリですので、見つかるはずではないかと思うのですが、なぜかエラーが出てしまうという状況です。 絶対パスにしますとちゃんと開けましたので、相対パスが無理なようでしたら絶対パスでいきたいと思います。 それと初めてみましたがGetModuleFileNameというものもあるのですね。 こちらも調べてみようと思います。 ありがとうございました。
- venzou
- ベストアンサー率71% (311/435)
実行時のカレントディレクトリが違うだけでは? >s=fopen("option.txt","r"); ファイル名をフルパスで指定してみてください。
補足
フルパスで指定するとちゃんと開けるようになりました。 ありがとうございます。
- nerosuke
- ベストアンサー率33% (39/115)
今一質問の意味が解りません。 argcは引数に渡った文字列の個数ですので、Drag&Dropは関係ないですよ。 仮にコマンドで "実行ファイル名" "ファイル名"でもDrag&Dropした処理になりますよ。 まあそれはいいのですけど、気になるのはfcloseをしてないことですね。 fopenで開いた"option.txt"を閉じてません。 しかしながら、それで質問者が陥ってる状態にはならないと思いますが ・・・ 開けなくなった状態でもoption.txtは存在しているんですか?
補足
指摘いただいたように、忘れていたファイルのクローズを試してみましたが、やはり状況は変わりませんでした。 option.txtはソースファイル・実行ファイルの存在するディレクトリにちゃんとあります。 パスの指定の方法は間違ってはいないと思うのですが…。
- 1
- 2
補足
そうですね、大学のPCにWindows98がひとつありますのでそれでの動作確認だけはしたいと思います。 こういう'\0'を挿入する方法は思いつきませんでしたね。 確認しましたが、こちらでも正常にフルパスが取得できました。 ちなみに、私の考えたプログラムはこのような感じです #include<stdio.h> #include<string.h> int main(int argc,char *argv[]) { char m[200]=""; char*j=strrchr(argv[0],'\\'); //後ろから最初の\を検索 int k=j-argv[0]+1; strncpy(m,argv[0],k); strcat(m,"option.txt"); printf("Path : %s\n",m); fflush(stdin); getchar(); }