
現在コマンドライン引数を利用した、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のテキストファイルが急に開けなくなってしまいました。
どうにも原因・解決策が分かりませんでしたので、お聞きしたくこちらに書き込みをさせてもらいました。
どなたか分かる方いらっしゃいましたらよろしくお願いします。
No.13ベストアンサー
- 回答日時:
#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();}
}
この回答への補足
そうですね、大学の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();
}
No.15
- 回答日時:
# 自分用(?)の簡単なツールのようなので蛇足かも知れませんが。
> char*j=strrchr(argv[0],'\\'); //後ろから最初の\を検索
この処理では、実行ファイル名に特定の漢字が入ると意図しない動作になりますね。
# わざわざ自作しなくても、パスだけ取るのは_splitpathで、合成は_makepathで可能だと思うのですが。
# (実際の関数名は、_splitpathのように先頭にアンダスコアがつきます)
この回答への補足
そういう問題があるのですか、知りませんでした。
特にファイル名には漢字等は使用しないので大丈夫かとは思われますが、_splitpathを用いたoption.txtのフルパスを取得する関数も別に自作してありますので、何か不都合があればこちらに切り替えることにしますね。
今まで教えていただいたことを参考に、一応プログラムが完成しました。
期待通りの出力が得られましたので、ひとまずこれでよしとしたいと思います。
これまで教えてくださった方々ありがとうございました。
No.14
- 回答日時:
凄いなぁ、ユーザが実行ファイルのファイル名を変えると動かなくなるプログラムですか。
あー、エクスプローラ上で、同じフォルダ内でコピペしただけでも動かなくなるんですね?
いや、凄いなぁ。「専門家」にはできない芸当ですね。
あ、念のために補足しておきますと、argv[0]にフルパスが入るか否かはOS依存じゃなくて処理系依存ですから。
つまり、BCCではなく他のコンパイラにすると使えなくなる(かもしれない)手法ってことです。
この件に関しては私も専門家ではないのでVCではどうなるか知りませんが、
少なくともgccでは巧くいかないことは判っています。
この回答への補足
>凄いなぁ、ユーザが実行ファイルのファイル名を変えると動かなくなる>プログラムですか。
>あー、エクスプローラ上で、同じフォルダ内でコピペしただけでも動か>なくなるんですね?
>いや、凄いなぁ。「専門家」にはできない芸当ですね。
???
>BCCではなく他のコンパイラにすると使えなくなる(かもしれない)手法っ>てことです。
なるほど、Windows98でもbccなら同様に動作するということですね。
それの確認も含めて、今度動作確認してみることにします。
No.12
- 回答日時:
念のための補足です。
C/C++の言語仕様では、argv[0]は「呼ばれたプログラム名」か「空文字("")」のいずれかが入ることになっており、
(まぁ現実にはPCで空文字って事は通常ないですが)
空でない場合も、ここでいうプログラムが絶対パスなのか、ユーザの入力文字列そのままなのか、
ファイル名だけなのか、等については規定されていません。
よって、argv[0]でフルパスが取れるか否かは処理系次第です。
# 入力文字がそのまま取れる奴とかもあります。
この回答への補足
argv[0]は処理系に左右されるのですね。
このプログラムは大学での実験データの解析に用いますので、大学のPCで使用できればそのまま使いたいと思います。
もし、不具合が起きるようならGetModuleFileNameの方を用いることにします。
補足ありがとうございました。
No.11
- 回答日時:
#include <stdio.h>
void main(int argc,char *argv[])
{
char c;
puts(argv[0]);
c = getchar();
}
実行ファイルのパスは argv[0] を見れば分かると思いますよ。
この回答への補足
argv[0]でパスは確認できたのですね。
そちらを用いて、最後の実行ファイル名を削除し、"option.txt"を追加する方法でoption.txtのフルパスを取得することができました。
ちなみに、先ほど教えていただいたGetModuleFileNameとsplitpathを使う方法でもフルパスを指定するのに成功しました。
しかし、argv[0]の方がシンプルなコードで表現できましたので、前者の方を採用したいと思います。
これで、思い通りのプログラムを組むことができそうです。
ご教授いただきありがとうございました。
No.8
- 回答日時:
"C:\Documents and Settings\[ユーザー名]"
ここだとすると、「止まっている」というより「ユーザのルート」かも。
直接D&Dしてるので、パスがそこになってるとか。
ためしに、デスクトップなどのユーザ配下ではないディレクトリに全ファイルを置いてD&Dするとどうなりますか。
それでも上記ディレクトリになるなら、止まっているわけではないことになるかと思います。
# GetModuleFileNameだと実行ファイルの絶対パスが取れるので、
# option.txtという名前からすると、上記をsplitpath等して、
# SetCurrentDirectoryとかする方がいいのかもしれませんが。
この回答への補足
ご指摘通り、"C:\"や"..\デスクトップ"など、いろいろなところで試してみましたが、すべてカレントは
"C:\Documents and Settings\[ユーザー名]"
となっていました。
ですので、MrBanさんのおっしゃるとおり「止まって」はいないようですね。
相対パスは無理そうなので諦めることにして、絶対パスの取得がGetModuleFileNameでできるということですので、勉強してこれから試してみることにします。
No.7
- 回答日時:
WindowsXP
Borland C++ Compiler 5.5
上記の環境で確認しましたが、Drag&Dropで起動すると、
C:\Documents and Settings\[ユーザー名]\
プログラムのパスにも、Drag元のパスにも関係なく、常に上記がカレントディレクトリでした。
きっとcmd.exeのデフォルト設定でしょう。
この回答への補足
私の環境も全く同じなので、何かこちらのバグというわけではないようですね。
仕方がありませんので、相対パスは諦めてフルパスでoption.txtを指定するようにします。
調べていただいて、どうもありがとうございました。
No.6
- 回答日時:
#include <stdio.h>
#include <windows.h>
void main(void)
{
char s[255];
char c;
GetCurrentDirectory(255,s);
printf("%s\n", s);
c = getchar();
}
こんな感じで、実行時のカレントディレクトリを確認すればすっきりするかも。
この回答への補足
カレントディレクトリを調べるコマンドがあったのですね。
試してみましたところ、
"C:\Documents and Settings\[ユーザー名]"
で止まっていました。
Drag元もDrop先もoption.txtも実行ファイルのある
"C:\Documents and Settings\[ユーザー名]\デスクトップ\Program"
に存在するので、このディレクトリがカレントになっているのが疑問です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/02/05 09:55
- C言語・C++・C# C言語のファイル入力が分かりません 2 2022/05/22 06:35
- Visual Basic(VBA) ExcelのVBAコードについて教えてください。 1 2023/08/09 10:33
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルvbaでdocuworksprinter...
-
Excel 相対パス
-
エクセルVBAで一つ上の階層...
-
xcopyコマンドの進行状況を表示...
-
コマンドプロンプトのコピー関...
-
C#でのProcess.Startと変数path
-
ExcelVBAの使い方 ¥の使い方...
-
実行ファイルのパスを取得したい
-
VBA★PDFをPDFアプリで印刷し...
-
初心者powershellのPS1ファイル...
-
パスワード保護されたExcelファ...
-
Eclipse
-
指定したフォルダ内の最新ファ...
-
SaveAsの保存先について
-
【VBA】複数のtxtファイルから...
-
ブラウザからファイルパスを取...
-
アクセス 自身のデータベース...
-
エクセルのマクロで特定フォル...
-
開いているファイルを削除し、...
-
コマンドプロンプトでファイル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルvbaでdocuworksprinter...
-
エクセルVBAで一つ上の階層...
-
xcopyコマンドの進行状況を表示...
-
Excel 相対パス
-
【VB.NET】App.configにファイ...
-
【VBA】ExcelマクロでCSVファイ...
-
エクセルのマクロで特定フォル...
-
実行ファイルのパスを取得したい
-
コマンドプロンプトのコピー関...
-
VBA★PDFをPDFアプリで印刷し...
-
VBAでパワーシェルを実行したい...
-
ExcelVBAの使い方 ¥の使い方...
-
C#でのProcess.Startと変数path
-
ExcelのVBAで上書き保存を確...
-
開いているファイルを削除し、...
-
アプリケーションのインストー...
-
【VBA】複数のtxtファイルから...
-
EXCEL(VBA)で指定フォルダ内の...
-
fopenでのパス指定
-
パスワード保護されたExcelファ...
おすすめ情報