實現輸出當前目錄下的文件名
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);
}
}
}
http://xxxxxx/Linuxjc/1183624.html TechArticle