貼代碼:函數
/*實現一個簡單的find命令:*/
/*程序思路:首先,用一個單鏈表將所須要的信息存儲起來;其次根據所傳入的參數信息,改變節點的狀態(如有這個狀態,證實該節點就是咱們所須要的)
最後將所須要的信息(文件名)打印出來,釋放節點存儲空間 */
/*加上一些信息:若僅僅運行程序(沒有輸入的參數),則將當前的目錄輸出,若僅僅只有1個參數(必須爲目錄)將該目錄下的信息輸出,接下來根據所給的
參數信息,執行相應的操做 */ui
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<dirent.h>
#include<sys/stat.h>指針
char *name;//保存輸入的參數(名字)字符串
/*每個節點就是一個文件的全部信息*/
typedef struct Node
{
char name[30];//存放文件的名稱;
struct stat info;//存放文件的屬性
int flag;//設置的狀態
struct Node * pNext;//指針域
}File;input
File *GetInfo(char dirname[]);
void do_find(int argc, char *argv[], File *pHead);
void do_free(File *pHead);
void change_name_flag(File *pHead);
void print(File *pHead);
void change_size_flag(File *, long);
void change_dir_flag(File *);
void change_cdev_flag(File *);
void change_bdev_flag(File *);
void change_gid_flag(File *, long);
void change_uid_flag(File *, long);string
int main(int argc, char *argv[])
{it
File *pHead = GetInfo(".");
do_find(argc, argv, pHead);
print(pHead);io
return 0;
}sed
/*將當前目錄裏面所須要的全部信息均保存在了所定義的結構體中*/
File * GetInfo(char dirname[])
{
File * pHead = (File *)malloc(sizeof(File));//構造一個頭節點
if (pHead == NULL)
exit(-1);
pHead->pNext = NULL;
File *pTail = pHead;//設置一個尾指針,方便循環體裏將全部節點連接file
DIR *dir_ptr;
struct dirent *direntp;
if ((dir_ptr = opendir(dirname)) == NULL)//打開目錄
fprintf(stderr, "cannot open %s\n", dirname);
else
{
while ((direntp = readdir(dir_ptr)) != NULL)//讀取目錄
{
File *pNew = (File *)malloc(sizeof(File));//生成一個新節點
if (pNew == NULL)
exit(-1);
strcpy(pNew->name, direntp->d_name);/*給數據域賦值*/
if (stat(pNew->name, &(pNew->info)) == -1)
perror(pNew->name);
pNew->flag = 1;
pTail->pNext = pNew;
pNew->pNext = NULL;
pTail = pNew;
}
closedir(dir_ptr);
}
return pHead;
}
void do_free(File *pHead)
{
File *p = pHead;
while (pHead != NULL)
{
p = pHead->pNext;
free(pHead);
pHead = p;
}
}
/*具體思路:好比:當傳入-name時,就要去判斷改變name的狀態,可是怎樣*/
/*根據傳入的參數執行相應的操做*/
void do_find(int argc, char *argv[], File *pHead)
{
int i=2;
while (i < argc)
{
if (strcmp(argv[i], "-name") == 0)//判斷輸入的參數是不是-name
{
if (i+1 < argc)//判斷後面是否還有輸入
{
name = argv[i+1];
change_name_flag(pHead);
}
else
{
printf("input name error!\n");
do_free(pHead);//先釋放空間,而後退出
exit(-1);
}
}
else if(strcmp(argv[i], "-size") == 0) //尺寸輸入的是數字,可是是做爲字符被識別的,所以須要使用字符串轉數字的函數(atoi)
{
if (i+1<argc)
{
change_size_flag(pHead, atoi(argv[i+1]));
}
else
{
printf("input size error!\n");
do_free(pHead);
exit(-1);
}
}
else if(strcmp(argv[i], "-type") == 0)/*下面這兩處代碼不規整,健壯性不夠, 具體參見上面的寫法*/
{
if (strcmp(argv[i+1], "-d") == 0)
change_dir_flag(pHead);
else if (strcmp(argv[i+1], "-") == 0)
change_file_flag(pHead);
else if (strcmp(argv[i+1], "-b") == 0)
change_bdev_flag(pHead);
else if (strcmp(argv[i+1], "-c") == 0)
change_cdev_flag(pHead);
else
{
}
}
else if (strcmp(argv[i], "-gid") == 0)/*經過id命令能夠查看當前的用戶號,查找時也是經過用戶號進行查找*/
{
change_gid_flag(pHead, atoi(argv[i+1]));
}
else if (strcmp(argv[i], "-uid") == 0)
{
change_uid_flag(pHead, atoi(argv[i+1]));
}
else
{}
i+=2;
}
}
void change_name_flag(File *pHead)//應該對目錄中的每一項進行一個遍歷
{
File *p = pHead->pNext;
while (p != NULL)
{
if (strstr(p->name, name) == NULL && p->flag == 1)//說明在節點中沒有與name相同的信息,標誌設爲0
p->flag = 0;
p = p->pNext;
}
}
void change_size_flag(File * pHead, long size)//atoi(argv[i+1])的結果是把字符串轉換爲數字(本例中的size)
{
File *p = pHead->pNext;
while (p != NULL)
{
if ((p->info).st_size > size && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void change_dir_flag(File *pHead)
{
File *p = pHead->pNext;
while (p != NULL)
{
if (!S_ISDIR(p->info.st_mode) && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void change_file_flag(File *pHead)
{
File *p = pHead->pNext;
while (p != NULL)
{
if (!S_ISREG(p->info.st_mode) && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void change_bdev_flag(File *pHead)
{
File *p = pHead->pNext;
while (p != NULL)
{
if (!S_ISBLK(p->info.st_mode) && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void change_cdev_flag(File *pHead)
{
File *p = pHead->pNext;
while (p != NULL)
{
if (!S_ISCHR(p->info.st_mode) && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void change_gid_flag(File *pHead, long gid)
{
File * p = pHead->pNext;
while (p != NULL)
{
if (p->info.st_gid != gid && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void change_uid_flag(File * pHead, long uid)
{
File * p = pHead->pNext;
while (p != NULL)
{
if (p->info.st_uid != uid && p->flag == 1)
p->flag = 0;
p = p->pNext;
}
}
void print(File *pHead)//打印出所須要的信息(對節點的每一項進行一個遍歷,若是狀態爲1,則將之打印出來){ File * p = pHead->pNext; while (p != NULL) { if (p->flag == 1) { printf("%s\n", p->name); } p = p->pNext; }}