概要
C言語の勉強と遊びを兼ねて。
フォーマット識別子はここを参考にした。
Linux上で動かすことを想定している。
ソースコード
/* * lsコマンドに、ディレクトリか通常ファイルかを判別して * 表示するプログラム。 * 引数は1個だけとる。その引数はlsコマンドで通常使われるような、 * 表示したいディレクトリのパス。 * ディレクトリか通常ファイルかjpgファイルか、を判別できるようにした。 * ディレクトリであれば、[DIR]が頭につく。 * jpgファイルであれば、[JPG]が頭につく。 */ #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> /* * jpgファイルかどうかを判別する。 * jpgファイルなら1を返す。 * jpgファイルでないなら0を返す。 * ファイルを開くことに失敗したら、-1を返す。 */ int chkjpg ( char *path ) { FILE *file; unsigned char buf[3]; int i, size; // マジックナンバーと比較する時に使うカウント用変数。 unsigned short int count = 0; // jpgファイルのマジックナンバー(フォーマット識別子) unsigned int jpg_magic[3] = { 255, 216, 255 }; // ファイルを開く。 file = fopen( path, "rb" ); if ( file == NULL ) { perror( "fopen" ); return -1; } size = fread( buf, 1, 3, file ); /* printf( "** chkjpg " ); for ( i = 0; i < size; i++ ) { printf( "%02x", buf[i] ); } printf( "\n" ); printf( "**chkjpg2 " ); for (i = 0; i < size; i++ ) { printf( "%d", buf[i] ); } printf( "\n" ); printf( "**chkjpg_compare " ); for ( i = 0; i < size; i++ ) { if ( buf[i] == magic[i] ) { printf( "OK!" ); } } printf( "\n" ); */ // マジックナンバーを比較する。正しければcount変数の値が増える。 for ( i = 0; i < size; i++ ) { if ( buf[i] == jpg_magic[i] ) { count++; } } fclose( file ); if ( count == size ) { return 1; } else { return 0; } } int main ( int argc, char *argv[] ) { // DIR型はdirent.hをincludeすると使えるようになる。 // ディレクトリを指し示す。 DIR *dir; // ディレクトリの中にあるファイルの情報を保持する。 struct dirent *dp; // dirent型よりもより詳しいファイルの情報を保持する。 struct stat sb; // Debianでのファイル名の文字数制限は255byteらしい。 // NAME_MAXはdirent.hをincludeすると使えるようになる。 char path[NAME_MAX * 2]; // 一時的にパスを格納する。最終的に絶対パスが入る。 char tmp_path[NAME_MAX * 2]; /* * 引数があるかどうかを判断して、無いならカレントディレクトリをpathに保存。 * 引数があるなら、その引数をpathに保存。 */ if ( argc <= 1 ) { strcpy( path, "." ); } else { strcpy( path, argv[1] ); } // ディレクトリを開く。 dir = opendir( path ); if ( dir == NULL ) { perror( "opendir" ); // exit関数はstdlib.hで定義されている。 exit( EXIT_FAILURE ); } // ディレクトリの中のファイルを見ていく。 for ( dp = readdir ( dir ); dp != NULL; dp = readdir ( dir ) ) { // stat関数に絶対パスが渡るようにする。 strcpy( tmp_path, path ); strcat( tmp_path, "/" ); strcat( tmp_path, dp -> d_name ); if ( stat( tmp_path, &sb ) == -1 ) { // perror( "stat" ); // closedir( dir ); // exit( EXIT_FAILURE ); continue; } // ディレクトリか通常ファイルかを判別。 if ( S_ISDIR( sb.st_mode ) ) { printf("[DIR]"); } else if ( chkjpg ( tmp_path ) ) { // jpgファイルか通常ファイルかを判別。 printf("[JPG]"); } // ファイル名を表示。 printf( "name : %s\n", dp -> d_name ); } closedir( dir ); exit( EXIT_SUCCESS ); }