C言語に、ファイルの存在の有無を確認できる
accessという関数があったと思うのですが
使用するヘッダファイルや引数、戻り値などを
説明できる方いらっしゃいましたらどうかお願いします。

accessを使用したらR_OK,F_OKとかいうマクロが
必要になったと思うのですが・・・

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

A 回答 (4件)

acceess()は元々UNIXのシステムコールであり、POSIX準拠OS以外では互換性が保証されません。


これはsignal()などとともに「移植性を阻害する標準関数」の筆頭に分類されます。

環境が指定されていないのでPOSIXのaccess(2)を想定します。

#inclue <io.h>
int access(const char *, int) ;
第1引数:ファイルパス名
第2引数:チェックするモード(0=存在、2=書きこみ、4=読み出し,6=読み書き)
関数値が-1の時、グローバル変数errnoに以下の値がセットされます。
EACCESS=指定したアクセス権が許可されていない
ENOENT=ファイルが損さしない
(errnoを使用するためにはerrno.hが必要)

ファイルの存在チェックだけならmacros.hのexist()マクロかstat(2)の方が楽なのではないでしょうか。
#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *, struct stat *) ;

#include <sys/types.h>
#include <sys/stat.h>
#include <macros.h>
int exist(const char *) ;

POSIX以外の処理系の場合、OSとコンパイラを指定してください。

この回答への補足

さっそくのご回答ありがとうございます。
さっそくWindows98のVisualC++と
VineLinuxとFreeBSDのgccで試してみました。
VCではio.hが存在したのですがgccでは存在しませんでした。又、macros.hはどちらにも存在しませんでした。


そこで、申し訳ないのですが、再び教えていただけないでしょうか?
VCでaccess関数を使ってみたのですが、戻り値が何を意味してるかがわかりません。
0と-1だけを返してるように見えますが、
0なら「O.Kです」、-1なら「ダメです」、というような解釈をしていいのでしょうか?


それとstat関数ですが、ファイルの存在チェックをする場合、
第2引数には何を与えればいいのでしょうか?
ちなみにVCのstat.h中の構造体statは以下のようになっています。

struct stat {
_dev_t st_dev;
_ino_t st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
_dev_t st_rdev;
_off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};

補足日時:2000/12/10 18:13
    • good
    • 0

それから、補足ですが、stat() を使うか、access() を使うかは、


用途が違うと考えてください。「ファイルの存在の有無を確認」の
意味によって、どちらを使うかが決まります。

本当に、存在するかどうかだけで以降の処理が決まるなら、stat()
を使うのがいいでしょう。ただし、シンボリックリンクとしてだけ
存在して、その先がなくてもいいなら、lstat() がいいかもしれま
せん。

それを読めるかどうか、書けるかどうかが重要な場合は access()
を使うべきです。しかし、単に読めるかどうか、書けるかどうかだ
けじゃなくてそれがファイルなのか、ディレクトリなのか、シンボ
リックリンクなのか、といった様々な可能性もチェックして正しい
処理をしたいという場合には、stat(), lstat() も併用する必要が
あります。

さらに、stat() してから、次のアクションを起こすまでに、誰か
がファイルを消したり、パーミションを落としたりしたら、どうし
たらいいかまで考えはじめると、きりがないですが…。
    • good
    • 0

stat() や access() 等のUNIXのシステムコール関数は、通常 man


に必要十分な情報が載っています。
man 2 stat
man 2 access
等、されてみたでしょうか?英語であったとしても、難しい文法は
使っていませんので、すぐに慣れると思います。OSによっては、日
本語のマニュアルが用意されている場合もありますが、かえってわ
かりにくいこともあるので、原文を参照する習慣をつけるのがいい
です。

例えば、FreeBSDの man によると、stat() の RETURN VALUES は、

 Upon successful completion a value of 0 is returned. Otherwise, a value of -1 is returned and errno is set to indicate the error.

ですので、「stat() が成功したとき(ファイルの属性が得られた
とき)に 0 を返し、それ以外では -1 を返して errno に値がセッ
トされる」という意味になります。どういうときに属性が得られな
いことがあるかというと、ERRORS の項を見ると、パスの途中にディ
レクトリでないものがあった、とか、名前が長すぎる、とか、ファ
イルが存在しない、とか、途中のディレクトリにアクセス許可がな
かった、とか、などなどです。

access() に関しても同様ですが、これの主な用途は、自分にとっ
てそのファイルが本当に読み書きできるかを調べるものですので、
可能なら 0 を返し、そうでなければ -1 を返します。ERRORS に関
しては似たようなものですが、-1 を返すかどうかは、どういうモー
ドでのアクセス可能性を問い合わせたかによって変化します。その
意味では、単にファイルのモード等を取り出すだけの stat() とは
異なります。また、access() では、ファイルシステムが readonly
のときに、書き込みができないこともチェックできます。(EROFS
がセットされる)

MSDNというのがマイクロソフトのサービスのことだとすれば、UNIX
に関する情報はあんまり期待できないのではないかと思いますが、
試したことがないのでわかりません。

errno を知りたければ、/usr/include/sys/errno.h を見るのはい
かがですか?ただし、各システムコールで、異なるエラーを同じ
errno で表現したりもしますから、結局 man を見て errno ごとの
意味を読み取るのが正確ですが。

manだけでは不安とか実例がいっぱい欲しいという場合には、書籍
もありますので、「UNIX システムコール プログラミング」などを
キーワードにして、検索してみてください。
    • good
    • 0
この回答へのお礼

とてもためになるお話をありがとうございます。おかげさまで自由に使えるくらいの知識ができたと思います。
書籍の件でもUNIXと聞いて、はっとしました。そういう本を探したことがありませんでした。そういえば他の方で書籍についての質問をしていた方がいましたので、そこを見れば非常に興味深い回答がありました。

それにしてもある程度Cができるようになったらその先はまずUNIXを学ばねばならないのでしょうか?
その辺に関わることをまた別の質問をしたいと思いますのでお暇がありましたらどうかよろしくお願いします。
では、回答をくださったおふた方様、ありがとうございました。

お礼日時:-0001/11/30 00:00

実は数日前にOSをクリーンインストールしてまして、GCC(Cygnus GNU Win32ですが)が入ってないんです。


すみません、GCCについてはちょっと時間がかかりますので他の方の回答が早いかもしれません。

POSIXを想定してたのでmacros.hを持ち出したのですが、ANSI標準ではないので他の処理系では存在しないかもしれません。

access()の関数値は
0=処理が正常に終了
-1=失敗
です。
第2引数が0の場合関数値が0なら「ファイルは存在する」なのですが、-1であっても「存在しない」とは限りません。
そこで、errnoで詳細を確認する必要が出てくるのです。
代表的な例としてはEINTRで、「割り込み発生」を示します。
この場合はファイルは存在します。

stat()の第2引数には常にstruct statのアドレスを渡します。

struct stat st ;
if (stat("c:\\xxx.dat", &st) == -1) {
switch (errno) {
case ENOENT :/* ファイル無し */
case EINTR : /* 割り込み発生(正常) */
default : /* その他のエラー */
perror("c:\\xxx.dat") ;
}
}
このような使い方になります。

なぜ、access()よりstat()をお勧めするかと言うと…。
access()の第2引数は処理系依存だからです。
MSDNでも_access()となっており互換性はWin95/NTです。

この回答への補足

本当にありがとうございます。おかげさまでファイルの存在チェックがだいたいマスターできました。
最後に少々お聞きしたいのですが、
stat関数の関数値とaccess関数の関数値は同じ意味であると解釈してもいいのでしょうか?

それと、どのような本を探せばこのような内容が説明してあるのでしょうか?このような内容や、errnoの全ての値の意味などを勉強してみたいと思うのですが、探し方が悪いのか、それとも住んでる所が田舎すぎるのか、sys内のヘッダファイルを使うような本を見たことがありません。

それともこれらの事はmanやMSDNで調べるべきなのでしょうか?

補足日時:2000/12/11 02:48
    • good
    • 0

この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) {
// ここに処理を書く
}
という関数が必要なようです。

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

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

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

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

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

Aベストアンサー

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

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

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

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Qfopne で失敗する原因

fopenで失敗する原因とはなんですか?

Aベストアンサー

#1の方の回答に加えて...

・ファイル名の文字列がでたらめ(存在するかどうか以前の問題)
・指定したファイル名が実はディレクトリだった。
・ファイル名に空ポインタまたは不正なポインタを渡した。
・オープンモードに空ポインタまたは不正なポインタを渡した。
・オープンモードの形式が不正
・メモリ不足でバッファ(実装によってはファイル記述子も)の割り付けに失敗した。
・同名の関数またはマクロをユーザーが定義した。
・関数原型なしで呼び出した。
・他のスレッド等で、同じファイルに対する操作中(再入可能とは限らないので)

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文字列がNULLか空文字列かの判定

Visual C++で、Cのプログラムを作成しているものです。(OS:WinNT 4.0)
文字列の扱いについて、質問します。

関数 int func(char *str) があると仮定します。
パラメータとして、strは以下のような状態あるとします。
(strは関数が呼ばれる前にcalloc()で領域確保済み)
 シンボル名 値
 str      0x00000001 ""
上記の状態で、strがNULLか空文字列("")であることを条件式にしたいのですが、str == NULL は偽となり、strcmp(str, "") を使用すると異常終了します。
どうしたらよいのでしょうか。アドバイスをお願いします。

Aベストアンサー

No1の方の回答にあるように、calloc()で取れた領域のアドレスを正しく渡せてないように思えますが...

#defineERROR(-1)

int func(char *str)
{
  if( (!str) || (!strlen(str)) ) return ERROR;
  return strlen(str);
}

void main()
{
  char *p=(char*)calloc(10,10);
  printf("%d\n",func(p));
}

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Q変数が""(空文字)かどうか判別する方法

度々お世話になります。

C++で""(空文字)かどうかを判別する方法はありますか?
私は単純にstrcmpで文字列比較をすればいいと思っていたのですが、
TLSを使用しているためか、なぜかうまくいきません。

// 変数宣言&取得(Setは省略)
__declspec( thread ) char tls_Name [12] = "";

const char * TlsGetName( void )
{
return tls_Name;
}

// 取得&判別(スレッド内処理)
if (strcmp(TlsGetName(),"") == 0)
処理A
else
処理B

このとき、初回実行時は処理Aに行ってくれるのですが
2回目の実行以降はtls_Nameが""であるにもかかわらず
処理Bに行ってしまいます。

どこかおかしな所やもっといい方法がありましたら教えてください。

Aベストアンサー

strlen()で長さが0であれば、空の文字列
もしくは
if( tls_Name[0]=='\0' ) {
文字列が空の時の処理
}


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

人気Q&Aランキング

おすすめ情報