こんにちは現在VC++を勉強しているのですが、
わからないことがありますのでご質問させていただきます。
ダイアログから取得した、拡張子とiniファイルに設定した拡張子を比較して、該当しなかっ
た場合にエラーを出させたいのですが、どのようにすればいいのでしょうか?
iniファイルは、アプリケーションごとに拡張子を設定します。
[fuzokuzu]
num=5
type1=jbw,jxw,jfw
type2=xls
type3=dxf,dwg
type4=jpg,tif
type5=pdf
です
ソースは
---------ダイアログから比較のボタンを選択された時の処理----------
filename = myDLG.GetPathName(); //ファイルパス取得
type1 = pApp->GetProfileString(fuzokuzu, type1, NULL);
if ((filename.Right(3),type1)){ //拡張子比較
//テスト用ポップアップ
AfxMessageBox(filename.Right(3) + type1);
}
--- 省略 ---
type5 = pApp->GetProfileString(fuzokuzu, type5, NULL);
if ((filename.Right(3),type1)){ //拡張子比較
//テスト用ポップアップ
AfxMessageBox(filename.Right(3) + type5);
}
これだと 問題が2つあります。文字列として比較した場合に jbw,jvw,jfw
とべつべつに比較してくれません。
それと、
type1からtype5までを一度に取得しフイルパスから取得した拡張子と比較したいができない。
ご教授お願いいたします。
ちょっと質問の主旨からは外れますが、私だったら、
[fuzokuzu]
num=9
jbw=type1
jxw=type1
jfw=type1
xls=type2
dxf=type3
dwg=type3
jpg=type4
tif=type4
pdf=type5
とiniファイルに定義して、取得したファイル名から拡張子を切り出して、それをキーに
してiniファイルを検索します。iniファイルに登録されている拡張子ならtypeいくつかが
返ってきますし、登録されていない拡張子ならエラー( GetProfileString()の第3引数に
与えた文字列が返ってくる )になります。
拡張子が3文字とは限らないので、「filename.Right(3)」を使うのは危険かと思います。
もしmyDLGがCFileDialogだったらCFileDialog::GetFileExt()で拡張子を取得するといい
でしょう。そうでなければ「最後に見つけたピリオド以降」としたほうがいいでしょう。
iniファイルを
[fuzokuzu]
num=5
type1=jbw,jxw,jfw
type2=xls
type3=dxf,dwg
type4=jpg,tif
type5=pdf
のままで使いたいのなら、GetProfileString()でとってきた値を
トークン分解するしかないでしょう。
VC7.0なら CStringT::Tokenize()があります。
ところで拡張子って filename.Right(3) でいいのでしょうか?
レスが送れてしまいすいません。tibさんとPIPさんの意見を参照させていただきました。
それで現在このように変更したのですが、
[fuzokuzu]
jbw=1
jxw=2
jfw=3
xls=4
dxf=5
dwg=6
jpg=7
tif=8
pdf=9
と設定し、
CWinApp* pApp = AfxGetApp();
//ファイル拡張子取得
CString fileName;
fileName = myDLG.GetFileExt();
//拡張子存否チェック
return_code = pApp->GetProfileInt(fuzokuzu,fileName , -1);
if (return_code ==-1){
AfxMessageBox(対象外拡張子);
AfxMessageBox(fileName);
}
//ファイル存在チェック
return_code = _access(filename,0);
if(return_code == -1){
AfxMessageBox(ファイルnathing);
}
やはり、
iniファイルを
num=5
type1=jbw,jxw,jfw
type2=xls
type3=dxf,dwg
type4=jpg,tif
type5=pdf
のようにして判断をしたいのですがどのようにすればいいのでしょうか??
>やはり、
>iniファイルを
>(略)
はう、だからトークン分解って書いたのに‥
具体的にはこうなるのかな。動作確認してませんが。
typedef std::multimap<CString, CString> StringMap;
typedef std::pair<CString, CString> StringPair;
StringMap extmap;
// iniから読んで、multimapに格納
for(int n=1; n<=5; ++n)
{
CString type; type.Format(type%d, n);
CString line;
int pos;
line = GetProfileString(fuzokuzu, type);
pos = 0;
CString ext = line.Tokenize(,, pos);
while(line != ")
{
extmap.insert(StringPair(type, ext));
CString ext = line.Tokenize(,, pos);
}
}
// 拡張子比較
for(int n=1; n<=5; ++n)
{
CString type; type.Format(type%d, n);
std::pair<StringMap::iterator, StringMap::iterator> x
= extmap.equal_range(type);
for(StringMap::iterator it = x.first; it != x.second; ++it)
{
if( filename.Right(3) == it->second ) // ここで拡張子と比較
{
// ここで拡張子と一致したので、処理を書く
}
}
}
おはよございます。PIPさんレスありがとうございます。
せっかくなのですが、VC++ 6なのでTokenizeがつかえませんでした。。
では strtok を調べてみましょう。
しかし、出来合いのものがないからできないと言っていないで、なければ自分で書けばいいので
す。
勉強中とのことですからちょうどいい練習問題じゃないでしょうか。
一応こんな風に作ってみました。
//ダイアログのOKだった場合
if (myDLG.DoModal()==IDOK){
int return_code;
int num;
CString type;
CWinApp* pApp = AfxGetApp();
enum fileType;
//ファイル拡張子取得
CString fileName;
fileName = myDLG.GetFileExt();
CString fileType;
num = pApp->GetProfileInt(fuzokuzu,num , -1);
for(int n=1; n<=num; ++n)
{
type.Format(type%d, n);
// AfxMessageBox(type);
fileType += pApp->GetProfileString(fuzokuzu,type , -1);
if(n!=num){
fileType += ,;
}
}
if(fileName="){
AfxMessageBox(拡張子がない);
}
//拡張子存否チェック
return_code= fileType.Find(fileName,2);
if (return_code ==-1){
AfxMessageBox(NOT FOUND);
} else {
filename = myDLG.GetPathName(); //ファイルパス取得
//ファイルの存在チェックをする
return_code = _access(filename,0);
if(return_code == -1){
AfxMessageBox(ファイルnathing);
}
}
}
多分、このコードでは拡張子に別のものが入ってきたら駄目だと思います。
たとえば、拡張子にhを指定してini上にhlpが入っていれば、ヒットして
しまいますよね。
あと、fileType.Find(fileName,2)で第二引数に2が入っているのが
よくわかりません。
VC6には、Tokenizeがありませんが、似たような動作をする関数はあります。
関数名ではなくてどんなことをする関数なのかを理解してそれに変わる物を
探すようにしないと応用が利かないと思います。
CString fileter;//後でヘッダファイルへ
CString filename; //後でヘッダファイルへ
int return_code;
int num;
CString type;
CWinApp* pApp = AfxGetApp();
CString fileType;
//フィルター表示させる拡張子設定
fileter += 全て(*.*)|*.*|;
fileter += 一太郎ファイル(*.jbw,*.jxw,*.jfw)|*.jbw;*.jxw;*.jfw|;
fileter += Excelファイル(*.xls)|*.xls|;
fileter += CADファイル(*.dwg,*.dxf)|*.dwg;*.dxf|;
fileter += フォトマジックファイル(*.jpg,*.tif)|*.jpg;*.tif||;
//ダイアログにオープン
CFileDialog myDLG( TRUE,全て(*.*),*.*, OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT,fileter);
// エクスプローラー風見
//myDLG.m_ofn.lpstrTitle = _T(アプリケーションの参照);
//myDLG.m_ofn.Flags += OFN_EXPLORER;
myDLG.m_ofn.lpstrInitialDir="; //最初のディレクトリ(指定があるかわからん)
//ダイアログのOKだった場合
if (myDLG.DoModal()==IDOK){
//ファイル拡張子取得
CString fileName;
fileName = myDLG.GetFileExt();
CString fileType;
//ファイル種別取得
num = pApp->GetProfileInt(fuzokuzu,num , -1);
for(int n=1; n<=num ; ++n)
{
//typeすべてを読み込む
type.Format(type%d, n);
fileType += pApp->GetProfileString(fuzokuzu,type , -1);
if(n!=num){
fileType += ,;
}
}
if(fileName=="){
AfxMessageBox(拡張子がない);
}
//拡張子存否チェック
return_code= fileType.Find(fileName);
if (return_code ==-1){
AfxMessageBox(NOT FOUND);
} else {
filename = myDLG.GetPathName(); //ファイルパス取得
//ファイルの存在チェックをする
return_code = _access(filename,0);
if(return_code == -1){
AfxMessageBox(ファイルnathing);
}
}
}
皆さん、お忙しいとこありがとうございます。 最終的にこのように落ち着いたんですが、
今度はiniファイルの拡張子をフィ
ルター表示させる拡張子に設定できるようにしようと思います。
みなさま、ありがとうございました。
まだまだ勉強が足りないことをじっかんしております。
またわからないことがあったときご質問させていただきたいと思います。