实现输出当前目录下的文件名
ls功能:
方法一:
#include <iostream> #include <algorithm> #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <sys/types.h> #include <string.h> #include <string> using namespace std; bool cmp( string s1,string s2){ return s1<s2; } int main() { DIR *dir; char s[100]; string data[100]; int tot=0; struct dirent *rent; dir =opendir("."); while(rent=readdir(dir)) { strcpy(s,rent->d_name); if(s[0]!='.'){ data[tot]=s; tot++; } } sort(data,data+tot,cmp); for(int i=0;i<tot;i++) cout<<data[i]<<" "; puts(""); closedir(dir); return 0; }
方法二:
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <pwd.h> #include <grp.h> #include <time.h> #include <dirent.h> int do_ls(char *dir,char *filename,int lflag) { int n; struct stat buf; char out[100]; struct passwd *pw; struct group *gr; struct tm *t; if(lflag == 0) //如果不带l参数,直接显示文件/目录名 { printf("%s\t",filename); return 0; } if(lstat(dir,&buf)<0) { fprintf(stderr,"stat error:%s\n",strerror(errno)); return -1; } switch(buf.st_mode & S_IFMT) //获取字符串的属性:普通文件-、目录d、字符设备c、块设备b、管道文件p、连接文件l、套接字文件s { case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; case S_IFIFO: printf("p"); break; case S_IFLNK: printf("l"); break; case S_IFSOCK: printf("s"); break; } for(n=8; n>=0; n--) //打印文件的读写属性:读r、写w、执行x、无权限- { if(buf.st_mode&(1<<n)) { switch(n%3) { case 2: printf("r"); break; case 1: printf("w"); break; case 0: printf("x"); break; default: break; } } else { printf("-"); } } printf(" %d",buf.st_nlink); //硬链接数,此链接非彼链接,指(包含)目录的个数,文件为1,目录起始为2,再加上目录里包含的目录个数(不递归,只一层) pw = getpwuid(buf.st_uid); //所属用户名 printf(" %s",pw->pw_name); gr = getgrgid(buf.st_gid); //所属组名 printf(" %s",gr->gr_name); printf(" %ld",buf.st_size); //字节计总大小 t = localtime(&buf.st_atime); //最后一次访问时间 printf(" %d-%d-%d %d:%d" ,t->tm_year+1900 ,t->tm_mon+1 ,t->tm_mday ,t->tm_hour ,t->tm_min); printf(" %s ",filename); if(S_ISLNK(buf.st_mode)) //判断是否为链接,是返回真 { printf(" -> "); if(readlink(filename,out,100)==-1) { //printf("readlink error\n"); } printf("%s",out); } printf("\n"); return 0; } int ls_prepare(char *w,int aflag,int lflag) //ls的准备工作 { struct stat buf; //man lstat可以看到此结构 char name[100]; DIR *dir; //类似打开文件的fd描述符 struct dirent *pdr; //man readdir可以看到此结构 if(lstat(w,&buf)<0) //获取文件/目录属性并赋值给buf,该函数和lstat一样,只是当w为链接时,指代他本身,并不存在文件 { fprintf(stderr,"stat error:%s\n",strerror(errno)); return -1; } if(S_ISDIR(buf.st_mode)) //判断是否为目录,是返回真 { dir = opendir(w); //打开目录 while ((pdr = readdir(dir))!=NULL) //读/遍历目录 { if(aflag==0) //如果不带a参数,越过以.开头的所有文件/目录 { if(pdr->d_name[0]=='.') continue; memset(name,0,100); strcpy(name,w); //拷贝 strcat(name,"/"); //追加 strcat(name,pdr->d_name); do_ls(name,pdr->d_name,lflag); } else //有a参数显示所有 { memset(name,0,100); strcpy(name,w); strcat(name,"/"); strcat(name,pdr->d_name); do_ls(name,pdr->d_name,lflag); } } closedir(dir); } else //为文件则直接显示 { do_ls(w,w,lflag); } return 0; } int main(int argc,char **argv) { int aflag =0; int lflag =0; char c; int i; while((c = getopt(argc,argv,"al"))!=-1) //解析命令行参数,即-/--后面的字符串和给定的字符串匹配,有未解析字母返回字母或问号(取决于第3个参数),否则返回-1 { switch(c) //此处仅匹配a(所有)和l(列表),即只支持参数a、l { case 'a': aflag =1; break; case 'l': lflag =1; break; default: break; } } if(argc == optind ) { ls_prepare("./",aflag,lflag); } else { for(i=optind; i<argc; i++) //所有目录都传进去 ls_prepare(argv[i],aflag,lflag); } printf("\n"); return 0; }
ls -l功能:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
void show_file_info(char* filename, struct stat* info_p) {
char* uid_to_name(), *ctime(), *gid_to_name(), *filemode();
void mode_to_letters();
char modestr[11];
mode_to_letters(info_p->st_mode, modestr);
printf("%s", modestr);
printf(" %4d", (int) info_p->st_nlink);
printf(" %-8s", uid_to_name(info_p->st_uid));
printf(" %-8s", gid_to_name(info_p->st_gid));
printf(" %8ld", (long) info_p->st_size);
printf(" %.12s", 4 + ctime(&info_p->st_mtime));
printf(" %s\n", filename);
}
void mode_to_letters(int mode, char str[]) {
strcpy(str, "----------");
if (S_ISDIR(mode)) {
str[0] = 'd';
}
if (S_ISCHR(mode)) {
str[0] = 'c';
}
if (S_ISBLK(mode)) {
str[0] = 'b';
}
if ((mode & S_IRUSR)) {
str[1] = 'r';
}
if ((mode & S_IWUSR)) {
str[2] = 'w';
}
if ((mode & S_IXUSR)) {
str[3] = 'x';
}
if ((mode & S_IRGRP)) {
str[4] = 'r';
}
if ((mode & S_IWGRP)) {
str[5] = 'w';
}
if ((mode & S_IXGRP)) {
str[6] = 'x';
}
if ((mode & S_IROTH)) {
str[7] = 'r';
}
if ((mode & S_IWOTH)) {
str[8] = 'w';
}
if ((mode & S_IXOTH)) {
str[9] = 'x';
}
}
char* uid_to_name(uid_t uid){
struct passwd* getpwuid(),* pw_ptr;
static char numstr[10];
if((pw_ptr = getpwuid(uid)) == NULL){
sprintf(numstr,"%d",uid);
return numstr;
}else{
return pw_ptr->pw_name;
}
}
char* gid_to_name(gid_t gid){
struct group* getgrgid(),* grp_ptr;
static char numstr[10];
if(( grp_ptr = getgrgid(gid)) == NULL){
sprintf(numstr,"%d",gid);
return numstr;
}else{
return grp_ptr->gr_name;
}
}
void do_ls(char dirname[]) {
DIR* dir_ptr;
struct dirent* direntp;
if ((dir_ptr = opendir(dirname)) == NULL) {
fprintf(stderr, "ls2: cannot open %s \n", dirname);
} else {
while ((direntp = readdir(dir_ptr)) != NULL) {
dostat(direntp->d_name);
}
close(dir_ptr);
}
}
void dostat(char* filename) {
struct stat info;
if (stat(filename, &info) == -1) {
perror(filename);
} else {
show_file_info(filename, &info);
}
}
int main(int ac,char* av[]){
if(ac == 1){
do_ls(".");
}else{
while(--ac){
printf("%s: \n",*++av);
do_ls(*av);
}
}
}