
FreeBSD5.4でstat()関数のS_ISDIRを使ってディレクトリかどうかを判別したいのですが、
S_ISDIRでは普通のファイルもディレクトリと認識してしまいます。もしご存知の方がいらっしゃいましたら、何卒ご教授くださいませ。
---------------------------------------------
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <stdlib.h>
int createFileList(char *directoryName){
DIR *directoryId;
struct dirent *directoryPointer;
struct stat fi;
directoryId=opendir(directoryName);
while((directoryPointer=readdir(directoryId))!=NULL){
stat(directoryPointer->d_name,&fi);
if (!S_ISDIR(fi.st_mode)) printf("%s\n",directoryPointer->d_name);
}
closedir(directoryId);
return 0;
}
---------------------------------------------
No.3ベストアンサー
- 回答日時:
int createFileList(char *directoryName){
で、カレントディレクトリのファイル(ディレクトリ)以外を指定すると、おそらく意図しない動作になります。
d_nameにはフルパス名ではないですし、stat()にそのまま渡すとカレントディレクトリから探しますし。
stat()でエラーしていれば-1が帰ってくるのでちゃんとチェックしてみてください。
具体的にどういうディレクトリでどういうパラメタを渡してどういう結果がになったかを書いたほうがいいでしょう。
自分で判断した結果を書くとそれが間違いだった場合、他の人には間違った情報を伝えることになるので、
正しい回答は得られません。
例えば、カレントディレクトリが/home/mirror-nameでcreateFileList("/tmp/")実行し、
/tmp/dummy.txtというファイルがあれば、
d_nameは"dummy.txt"となり、stat()を実行すると
/home/mirror-name/dummy.txtの情報を得ようとします。
この時にファイルがなければエラーとなり、fiの内容は正しく設定されないことになります。
C言語でディレクトリが扱えないとか、こんな程度で限界ということはありません。
この回答への補足
お返事有難うございます。一番上のソースコードに加えて、
---------------------------------------------
int main(int argc,char *argv[]){
createFileList(argv[1]);
return 0;
}
---------------------------------------------
を付け足して、
localhost# gcc -o directoryDistinction directoryDistinction.c
でコンパイル後、
localhost#./directoryDistinction /home/sampleuser/public_html
などで実行しました。
いろいろ試してみると「/」 では正常に判別できるのに階層が深くなるディレクトリだと通常ファイルも全てがディレクトリと判別してしまうようです。
自分もC言語は大好きです。。。きっとUNIX系がいけないんでしょう。
No.4
- 回答日時:
#include<sys/dir.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
main()
{
DIR *dp;
struct direct *dir;
struct stat sbuf;
int i;
size_t size;
char *aa;
char *buf;
if( ( dp = opendir(".") ) == NULL ){
fprintf(stderr,"cannot open directory.\n");
exit(1);
}
getcwd( aa,255);
/*printf("現在のディレクトリーは、(%s)です。\n",aa);*/
i =0;
while( ( dir = readdir(dp) ) != NULL ){
if( dir->d_ino == 0 )
continue;
stat( dir->d_name, &sbuf);
switch( sbuf.st_mode & S_IFMT ){
case S_IFDIR:
printf("<d>");
break;
default:
printf("<f>");
}
if( i > 2 ){
printf("%s\n",dir->d_name);
i = 0;
}else{
printf("%-10s",dir->d_name);
if(strlen(dir->d_name) >= 10 )
printf("\n");
i++;
}
}
printf("\n");
closedir(dp);
exit(0);
}
昔なにげに作ったプログラムです。
31行目のswitchからがファイルかディレクトリかの
判別部分です。
Linuxでは動いた記憶があります。
ただ参考にした本がアスキー出版社のUNIX Cプログラミング
と言う本で本来Linuxを対象にした物でなくて
SystemV系・BSD系を対象にした本を参考にして
作りました。
この回答への補足
お返事有難うございます。やはり実行結果は同じに、
階層が深いディレクトリだと通常ファイルなど全てのファイルに<d>がつきます。しかし<d>や<f>がついて非常に見やすかったので、下の人の補足ができました。有難うございます。やはりUnixやLinuxでは難しいのかな?
No.2
- 回答日時:
S_ISDIR の定義を確認してみては。
Mac OS X(Tiger)付属のsys/stat.hですと、
if ( S_ISDIR( fi.st_mode ) ){ /* ディレクトリの場合 */ }
――が正しい判定法です。
この回答への補足
お返事有難うございます。早速/usr/include/sys/stat.hをgrep S_ISDIRしてみました。
#define S_ISDIR(m) (((m) & 0170000) == 0040000)
となっていまして、使用法にかんしては・・よく分かりません。。書籍やサイトなどで紹介されている使用方法をとっているので間違いはないとは思います。
やはりC言語の限界なのでしょうか?
No.1
- 回答日時:
条件判定部分を
if ((fi.st_mode & S_IFMT == S_IFDIR))
としてはどうでしょうか。
参考URL:http://www.linux.or.jp/JM/html/LDP_man-pages/man …
この回答への補足
お返事有難うございます。
早速やってみましたが、やはりディレクトリも通常ファイルも表示されませんでした。
FedoraCore4でも同じ結果でした。やはり、C言語ではディレクトリは扱えないのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ファイル名と更新日付の取得に...
-
batファイルでrenameができませ...
-
ディレクトリの判別
-
vba dir の相対パス
-
空白を含むディレクトリにある...
-
C言語でファイル名を取得
-
cookieの削除
-
FindFirstFileとFindNextFileで...
-
ディレクトリ名を取得したい
-
一定時間が経過したフォルダの削除
-
サーバーにある特定の拡張子フ...
-
全角と半角文字が混在している...
-
fgets で値が取得できない
-
ファイル名の切捨てとリンクの...
-
perl ファイルが開かない
-
ReadLineでの読み出し行を指定する
-
文字コードの変換(Shift-JISか...
-
close()で例外が投げられる理由
-
perlで、後ろの行を読んで、前...
-
Perl<->Oracle間での文字化けに...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Windowsで複数のファイルを同じ...
-
batファイルでrenameができませ...
-
vba dir の相対パス
-
パスから最後のディレクトリだ...
-
FindFirstFileとFindNextFileで...
-
readdir()で得られるファイル・...
-
ディレクトリー内のリスト出力...
-
ファイル名と更新日付の取得に...
-
C言語でファイル名を取得
-
ファイルの削除について
-
シェルでfind結果を文字列で比...
-
dos変数の%~dp0は powershellで...
-
フォルダに入っているファイル...
-
サーバー内にある指定した拡張...
-
CGIで日本語名ファイルのアップ...
-
find関数が1階層(カレントディ...
-
下のディレクトリ(3つ)に含ま...
-
ファイル名が日本語の物をダウ...
-
<>の意味が分かりません
-
makefileでファイルをコピー(...
おすすめ情報