こんにちは。

VC++を使用してWindows上で動作するプログラムを作成しているのですが、ユーザに絶対パスをテキストで入力させ、そのパスが存在しなければ、フォルダとファイルを新規作成するかどうか問い合わせるという処理を行いたいと考えています。

 そこで質問なのですが、
・有効なパス設定で存在しないフォルダ
・無効なパス

上記を判定したいのですが、現状区別が付けられないでいます。実際には、以下のように処理しています。
OutputFilename:CString型、絶対パス(ファイル名含む)が入っている。
OutputPath:CString型、絶対パス(上記から「\ファイル名」を除いたもの)

// 出力ファイルのパス存在チェック
pathlen = OutputFilename.ReverseFind('\x5c');// 最後の\記号までの文字数を取得
if(pathlen == -1)
return -1; // エラー
OutputPath = OutputFilename.GetBufferSetLength(pathlen);
nRcd = _chdir(OutputPath);
if(nRcd){
if(errno == ENOENT)
return -1; ※
}

※無効なパス(例えばabc\bcd\efgなど)であっても、存在しないパス(例えばC:\tempは存在し、その配下には存在しないフォルダ名を指定-C:\temp\abc\def)であっても、同様に_chdir関数が失敗し、errnoにENOENTが入るようです。

どなたかご存知の方がおられましたら、どうかご教授お願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

Win32 API BOOL PathIsDirectory(LPCTSTR Path);



-------------
char *Path = "c:\\windows\\";

if (PathIsDirectory(Path)) printf("'%s'は正しいディレクトリである。\n", Path1);
else printf("'%s'は正しいディレクトリでない。\n", Path);
--------------
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
お礼が遅くなり、申し訳ありません。

結局、GetDriveTypeと実際に作成を試みて成功するかどうかで判定することにしました。

どうもありがとうございました。

お礼日時:2005/04/25 14:20

色々な方法があると思いますが、他の方も言われているように実際にアクセスしてみるのが堅実だと思います。

他には、軽くFind系で探してみる手もあります。

それから問い合わせするのであれば、うるさいユーザーの為にも書き込み不可能なCD-ROMやネッワークパスを入力された場合、マヌケなメッセージを出さないような配慮も必要ですね。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
お礼が遅くなり、申し訳ありません。

結局、GetDriveTypeと実際に作成を試みて成功するかどうかで判定することにしました。

どうもありがとうございました。

お礼日時:2005/04/25 14:17

::GetFileAttribute()を使って


そこにファイルがあるかディレクトリがあるか
あるいは存在しないかを調べるとよいでしょう。

パスの有効性を調べるには
とりあえず::CreateFileしてみるのでは駄目ですか?

あと
OutputFilename.ReverseFind('\x5c'); は危険かも
最後のパスが漢字だったりする場合に
あやまって検出する可能性があります。

移「0x835C」にひっかかったり
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
お礼が遅くなり、申し訳ありません。

結局、GetDriveTypeと実際に作成を試みて成功するかどうかで判定することにしました。

どうもありがとうございました。

お礼日時:2005/04/25 14:13

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qファイルやディレクトリの存在確認を行う方法

ファイルをオープンするのはfopenでOKですが、ファイルやディレクトリの存在確認を行う方法が知りたいです。

何か組み合わせて作るものなのでしょうか?
perlとか便利な演算子があるのですが、C/C++って器用ではないですね。
これは処理系?依存の内容ですか?

私の環境は VC6, VC2005 Windows2000です。

Aベストアンサー

int access(const char* path, int mode);
int stat(const char* path, struct stat* sb);

かな?
MSDN を引くと _access_s() を使えとか書いてあるけど。

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QCString から LPCTSTRの型に変換

visual studio 2013 VC++を使用していますが、WINDOWSの関数に渡すためにCString からLPCTSTRに変換する必要があります。実際にどのようにするのかわかりません。
例えば、以下のサンプルは他の質問コーナーの回答をアレンジしたものです

CString str = _T("ABC");
int siz = str.GetLength()+1;
LPCTSTR pszFName = new TCHAR[siz];
_tcscpy_s( pszFName, siz, str );

で変換するのですが
LPCTSTRからwchar_t*へ変換できませんとエラーがでます
_tcscpy_s()は使用できないのでしょうか

Aベストアンサー

>APIはCStdioFile の Open()でファイル名を与えるところ

APIではないようですが……。

http://msdn.microsoft.com/ja-jp/library/ee247566.aspx
ならば、そのままCStringの変数渡せば、よろしく処理してくれると思いますけど。

QC ファイル出力で、フォルダがない場合でも作成する方法

先日、皆さんに教えていただき

Cで出力ファイルを指定のフォルダに出す方法が上手く出来ました。
具体的には、↓こうやって指定しました。
sprintf( buff, "%s\\%s", path, filename );

やっていて思ったのですが、
この方法だと、指定フォルダが最初から無いとエラーが出てしまいます。
フォルダが無かったら、作成し、その中にファイルを出力していってくれる。という方法はできるものなのでしょうか?

もしできるようなら教えて下さい!!
よろしくお願いします!

Aベストアンサー

★回答ではないが余談。
・koko_u_ さんありがとう。
 気づくとアンダーバーの関数名で置き換わっているみたいですね。
 他にも気づくといろいろ置き換わっていますね。
 C 関数、最近使っていないのでアンダーバーの関数名で調べてみます。
・ありがとうございました。

●質問者さんへ。
・_mkdir() 関数が使える場合はその関数でもフォルダ(ディレクトリ)が作成できます。
 それでは。

参考URL:http://www5c.biglobe.ne.jp/~ecb/c/12_14.html

Qフルパスから最後のディレクトリ名を取得したい。

vb.netなのですが、例えば
c:\aaa\bbb\ccc\ddd\eee\fff.exe
というフルパスがあったとして、
eeeというディレクトリ名を取得したいのですが、
何か良い方法はないでしょうか。
それぞれのディレクトリ名の文字数や階層数は
決まっていないのですが、オススメの方法が
ありましたら、教えて頂けると助かります。

Aベストアンサー

MessageBox.Show(IO.Path.GetFileName(IO.Path.GetDirectoryName(myPath)))

IO.Path の GetDirectoryName でフォルダのフルパスを取得して、さらに IO.Path の GetFileName で最終フォルダ(またはファイル)の名前を取得。

QC++ 構造体の一括初期化 {0}

構造体変数に {0} を代入すると、CString は空文字、 intは0に一括で初期化されるようです。
なんでこんなことが出来るのでしょう?
{0}は何?
仕組みを教えて下さい!!

Aベストアンサー

> 一括初期化関数でも作るしかなさそうですね
static変数を初期化用に用意しておくのはいかが?
http://oshiete.goo.ne.jp/qa/2658268.htmlより
>静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、
>次の規定に従う。
>a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。
>b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。
>c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に)
>適用し初期化する。
>d) そのオブジェクトが共用体の場合、最初の名前つきメンバにa)~d)の規定を
>(再帰的に)適用し初期化する。

なので、zero初期化されていることが、規格で保証されます。

typedef struct hoge_struct
{
 int a;
 int b;
} hoge_struct;

static hoge_struct initializer; //初期化用変数。値は変えない。

int main(void)
{
 hoge_struct hoge;
 hoge = initializer;
 return 0;
}
真っ白に何度も初期化したいなら、こんな感じでどうでしょう?
関数を用意して初期化すると、構造体のメンバが増えると関数も修正しないといけない
ですが、これだと関数を変更しなくてすむし。

> 一括初期化関数でも作るしかなさそうですね
static変数を初期化用に用意しておくのはいかが?
http://oshiete.goo.ne.jp/qa/2658268.htmlより
>静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、
>次の規定に従う。
>a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。
>b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。
>c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に)
>適用し初期化する。
>d) そのオブジェクトが共用...続きを読む

QC++言語で、構造体のコピーは可能(しても良い)のでしょうか?

C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
問題がある場合は、なぜだめなのか知りたいです。
構造体は可変長ではありません。

typedef struct kumi {
char namae[10];
int ten;
}Kumi;

Kumi a, b;

strcpy(a.namae, "AAA");
a.ten = 50;

b = a;

Aベストアンサー

「C++」では何の問題もありません.
「C」だと, ふる~い時代の遺跡級のコンパイラが文句を言うかもしれません. ま, その手の遺跡級のコンパイラだと
・void がない (void * は char * で代用する)
・プロトタイプが存在しない
・const や volatile がない
・ひょっとすると単項の + もない
など, 今の視点からするといいたいことは山ほどあります (さすがに a -= b; ではなく a =- b; とするコンパイラを使うことはないだろう).
そのような時代には構造体のコピーを memcpy でやっていましたが, C++ では逆に危険です.

Q初級者の質問――time_tについて

私はC言語の初級者です。

time関数というのは現在時刻をtime_t型で返すものですよね。
でも、私はこの意味がよくわかりません。

time_t型とは何でしょうか。

単なる整数なのでしょうか。
確か、time_t型というのは整数で、
1970年1月1日0時からの秒数(世界標準時)だと聞いた気がします。

しかし、(いくつか見てみましたが)大抵のC言語の本では、そういう説明はしていません。
「プログラミング言語C」(カーニハン、リッチー)という本では、
「timeは現在のカレンダー時間を返す。」
と説明しています。
「じゃあ、カレンダー時間って何?」と思いますが、「カレンダー時間」というものの説明は見当たりません。

time_tというのは整数と考えてよいのでしょうか。
time_tで変数宣言すると、プログラムを読む人が「あ、これは時間を表すんだな」とわかり易いから、time_tというものがあるのでしょうか。

それとも、
time_tが秒数を表すかどうかは処理系に依存するのでしょうか。

もし、1970年1月1日からの秒数を表すなら、time関数の戻り値を1年間の秒数で割って1970に足せば今何年かわかるプログラムになりそうですよね。(うるう年や時差は考慮する)
それとも、それは処理系によっては正しく動かないプログラムになるのでしょうか。
(あくまでも考え方です。確か、time_tを渡せば年月日時分秒を返す関数があると思います。)



ちなみに、おとといプログラムを作ってtime関数の戻り値を10進数で表示すると次のようになりました。(VC++)


==============プログラム==============

#include <stdio.h>
#include <time.h>

int main(void)
{
time_t a;
a=time(NULL);
printf("%d\n",a);

return(0);
}

================結果===============

1005300371

私はC言語の初級者です。

time関数というのは現在時刻をtime_t型で返すものですよね。
でも、私はこの意味がよくわかりません。

time_t型とは何でしょうか。

単なる整数なのでしょうか。
確か、time_t型というのは整数で、
1970年1月1日0時からの秒数(世界標準時)だと聞いた気がします。

しかし、(いくつか見てみましたが)大抵のC言語の本では、そういう説明はしていません。
「プログラミング言語C」(カーニハン、リッチー)という本では、
「timeは現在のカレンダー時間を返す。」
と...続きを読む

Aベストアンサー

> C99とは、ISOの規格で比較的新しいものと思います。

そうです。
正式にはISO/IEC 9899:1999です。

> (C98というのは知りませんでした。)
失礼しました。
C89の間違いです。
同様にISO/IEC 9899:1989です。

> しかし、時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、かまわないのでしょうか
時間の起点(というか、時間の管理方法)は time()の管轄であり、型であるtime_tは「time()が返す値を表現できること」が要求されているに過ぎません。
また、「1970年1月1日0時0分0秒からの経過秒数」というのは慣例に過ぎません。

とはいえ、UNIXを起源とする『time_tはlong』と『time()は1970年1月1日0時0分0秒からの経過秒数』という約束事は変えられる事は無いでしょう。
C98/C89との互換性を保ちながら新規格を作ることが予想されるからです(そうでなければlong longなどという型は作らないはず)。
その意味でyoushirさんのおっしゃるとおりだと思います。

> C99とは、ISOの規格で比較的新しいものと思います。

そうです。
正式にはISO/IEC 9899:1999です。

> (C98というのは知りませんでした。)
失礼しました。
C89の間違いです。
同様にISO/IEC 9899:1989です。

> しかし、時間の起点が2000年1月1日であっても、秒数でなくて日数であっても、かまわないのでしょうか
時間の起点(というか、時間の管理方法)は time()の管轄であり、型であるtime_tは「time()が返す値を表現できること」が要求されているに過ぎません。
また、「1970年1月1日0...続きを読む

QGetPrivateProfileStringでiniファイル読込む処理を詳しく知りたいのですが・・・

お世話になっています。

iniファイルを読込み、各変数に代入するC言語のDLLを作成したいのです。
このサイトの投稿や、MSDNなどにも載っていたのですが、
少し理解に苦しみます。

現在まで、理解した点がwindows.hのインクルードを
記述するところ辺りです。
iniファイルは下記のようなレイアウトです。

---<mst.ini>----------------------------
[user]
name=username
ID=userid
[pc]
pcname=FMV
----------------------------------------

#include<windows.h>は記述することまでは
分かりましたが、以下から進みません。。。

GetPrivateProfileString("")

初心者で申し訳ありませんが、お助け願います。

Aベストアンサー

こんにちは。itohhといいます。

サンプルを載せておきます。

mst.iniファイル内の[user]セクションのnameキーの値を取得する。
DWORD dwLen=0;
char strBuf[100];
dwLen = GetPrivateProfileString("user",       // セクション名
                "name",       // キー名
                "soushi_ni",     // デフォルト値
                strBuf,       // 読み込んだ値を格納するエリア
                sizeof(strBuf),   // 上記のエリアのサイズ
                "mst.ini" );     // iniファイル名

解説:
iniファイル名をフルパスで指定しないとWindowsのディレクトリにあるものと判断されます。
Win9xなら「c:\windows」、WinNT系なら「c:\WinNT」。

[user]セクションのnameキーがないときは、デフォルト値で指定した値が設定させます。

復帰値「dwLen」は実際に設定した値(文字列)の長さが返されます。

こんにちは。itohhといいます。

サンプルを載せておきます。

mst.iniファイル内の[user]セクションのnameキーの値を取得する。
DWORD dwLen=0;
char strBuf[100];
dwLen = GetPrivateProfileString("user",       // セクション名
                "name",       // キー名
                "soushi_ni",     // デフォルト値
                strBuf,       // 読み込んだ値を格納するエリア
             ...続きを読む

Q実行ファイルのパスを取得したい

C言語で自分自身がどのディレクトリに存在しているか
知りたいのです。

簡単に例を挙げて説明します。

UNIX C言語で cmd1 という実行ファイルを作成しました。
環境変数は以下のように定義されていたとします。
PATH=/bin:/usr/bin

/binにcmd1を配置してカレントディレクトリ/homeにおいて
cmd1を実行、cmd1プログラム内で"/bin/cmd1" を取得したいのです。
続けて、/bin/cmd1を/usr/bin/cmd1移動して、cmd1を実行すれば、
プログラム内で"/usr/bin/cmd1"を取得できるコーディングをしたいのです。

typeコマンドのような事をC言語で行いたいのですが。

お分かりの方いらっしゃいましたら教えてください。

よろしくお願いします。

Aベストアンサー

>C:\WINDOWS\COMMAND\CMD1.EXE
>と表示されます。
>この違いはなんだろう?

C:\windows\commandってフォルダに突っ込んでる時点でOSがぜんぜん違いますよね。
Win9xとNT系じゃ。

9x系はフルパスが、NT系は起動時の実行コマンドargv[0]には格納されています。

UNIXでは実行モジュールのフルパスを取得する一般的な方法は無いみたいです。

Windowsでは#4の方の書かれているとおり、GetModuleFileName()です。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報