編寫一個程序,令其功能儘量向命令 “ls -l” 靠近

更多資料請點擊:我的目錄

本篇僅用於記錄自己所學知識及應用,代碼仍可優化,僅供參考,如果發現有錯誤的地方,儘管留言於我,謝謝。
效果如下:

#include <grp.h>
#include <pwd.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <strings.h>
#include <sys/stat.h>

char *type_perm(mode_t mode);

int main(int argc, char **argv)
{
	// 確認參數個數
	if(argc > 2)
	{
		printf("輸入錯誤!用法:<目錄>\n");
		exit(0);
	}

	struct stat info;
	bzero(&info, sizeof(info));
	stat(argv[1], &info);

	//獲取用戶名的結構體與定義
	struct passwd *my_info;
	my_info =getpwuid( getuid() );

	//獲取用戶組名的結構體與定義
	struct group *my_gid;
   	my_gid = getgrgid( getgid());
		
	char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

	if(S_ISDIR(info.st_mode))
	{
		// 打開目錄: 獲取目錄的訪問入口
		DIR *dp = opendir(argv[1]);
		chdir(argv[1]);

		if(dp == NULL)
		{
			printf("打開目錄[%s]失敗\n", argv[1]);
			exit(0);
		}

		// 不斷地讀取目錄項
		struct dirent *ep;
		while(1)
		{
			// 讀取目錄,得到目錄項指針
			ep = readdir(dp);
			// 讀完了全部目錄項
			if(ep == NULL)
				break;

			// 跳過隱藏文件
			if(ep->d_name[0] == '.')
				continue;
			
			bzero(&info, sizeof(info));
			stat(ep->d_name, &info);
			
			//獲取時間的結構體與定義
			time_t timep;		
		   	struct tm *p;			
			ctime(&info.st_mtim.tv_sec);
		   	p = localtime(&info.st_mtim.tv_sec);

			//輸出文件類型和權限
			printf("%s ", type_perm(info.st_mode));

			// 輸出鏈向此文件的連接數(硬連接)		
			printf("%ld ",info.st_nlink);

			// 輸出文件的所有者
			printf("%s ",my_info->pw_name);
			
			// 輸出文件的所在組
			printf("%s",my_gid->gr_name);

			// 定間隔輸出文件的大小
			printf("%8ld ", info.st_size);
			
			// 定間隔輸出文件的最近修改時間
			printf("%s %2d %2d:%2d  ", wday[p->tm_wday], p->tm_mday, p->tm_hour, p->tm_min);
			
			// 輸出名字
			printf("%s\n", ep->d_name); 
		}
		closedir(dp);
	}

	else
	{
		//獲取時間的結構體與定義
		time_t timep;		
	   	struct tm *p;			
		ctime(&info.st_mtim.tv_sec);
	   	p = localtime(&info.st_mtim.tv_sec);
		
		//輸出文件類型和權限
		printf("%s ", type_perm(info.st_mode));

		// 輸出鏈向此文件的連接數(硬連接)		
		printf("%ld ",info.st_nlink);

		// 輸出文件的所有者
		printf("%s ",my_info->pw_name);
		
		// 輸出文件的所在組
		printf("%s ",my_gid->gr_name);

		// 定間隔輸出文件的大小
		printf("%4ld ", info.st_size);
		
		// 定間隔輸出文件的最近修改時間
		printf("%s %2d %2d:%2d  ", wday[p->tm_wday], p->tm_mday, p->tm_hour, p->tm_min);
		
		// 輸出名字
		printf("%s\n", argv[1]); 
	}
	return 0;
}

char *type_perm(mode_t mode)
{
	static char result[11];

	switch(mode & S_IFMT)
	{
		case S_IFBLK: result[0] = 'b'; break;
		case S_IFCHR: result[0] = 'c'; break;
		case S_IFREG: result[0] = '-'; break;
		case S_IFIFO: result[0] = 'p'; break;
		case S_IFSOCK:result[0] = 's'; break;
		case S_IFLNK: result[0] = 'l'; break;
		case S_IFDIR: result[0] = 'd'; break;
	}

	char rwx[] = {'r', 'w', 'x'};
	for(int i=0; i<9; i++)
	{
		result[i+1] = mode&(0400>>i) ? rwx[i%3] : '-';
	}
	return result;
}

更多資料請點擊:我的目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章