您的位置:首页 > 其它

文件目录和库

2015-08-06 08:29 381 查看
一、编写一个简易ls命令程序。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <dirent.h>
#include <string.h>

//可用不同颜色字体标识不同文件类型
#define GRAY    "\033[0m"
#define RED     "\033[1m\033[0;31m"
#define GREEN   "\033[1m\033[0;32m"
#define YELLOW  "\033[1m\033[0;33m"
#define BLU     "\033[1m\033[0;34m"
#define MAGENTA "\033[1m\033[0;35m"
#define CYAN    "\033[1m\033[0;36m"
#define WHITE   "\033[1m\033[0;37m"

static int mygetopt(int argc,char *argv[])  //分解命令行参数
{
int ch;
if((ch=getopt(argc,argv,"la"))!=-1)
{
if(ch == 'a')
{
if((ch=getopt(argc,argv,"la"))!=-1)
{
switch(ch)
{
case 'l':
if((ch=getopt(argc,argv,"la"))!=-1)
return -1;
return 3;               //命令行参数为-al
break;
default:
return -1;
}
}
else
return 2;                  //命令行参数为-a
}

if(ch == 'l')
{
if((ch=getopt(argc,argv,"la"))!=-1)
{
switch(ch)
{
case 'a':
if((ch=getopt(argc,argv,"la"))!=-1)
return -1;
return 3;            //命令行参数为-la
break;
default:
return -1;
}
}
else
return 1;             //命令行参数为-l
}
else
return -1;
}
return 0;
}

static void myls_l(struct dirent *ep)        //参数有l时的显示函数
{
char t[40];
int fd,i;
struct stat buf;

if((fd=open(ep->d_name,O_RDONLY))<0)
{
perror("open");
exit(-1);
}

if(fstat(fd,&buf)<0)
{
perror("fstat");
exit(EXIT_FAILURE);
}

if(S_ISREG(buf.st_mode))                             //文件类型
printf("-");
else if(S_ISDIR(buf.st_mode))
printf("d");
else if(S_ISCHR(buf.st_mode))
printf("c");
else if(S_ISBLK(buf.st_mode))
printf("b");
else if(S_ISFIFO(buf.st_mode))
printf("p");
else if(S_ISLNK(buf.st_mode))
printf("l");
else if(S_ISSOCK(buf.st_mode))
printf("d");
printf("%o ",buf.st_mode & ~(S_IFMT));                //权限
printf("%d ",buf.st_nlink);                           //硬链接数量
printf("%d ",buf.st_uid);                             //所有者用户ID
printf("%d ",buf.st_gid);                             //所有者组ID
printf("%ld ",buf.st_size);                            //文件大小
printf("%d %d ",major(buf.st_dev),minor(buf.st_dev)); //主从设备号
printf("%ld ",buf.st_ino);	                          //索引节点
strcpy(t,ctime(&buf.st_atime));                       //上一次访问时间
for(i=0 ; t[i]!='\n'&&t[i]!='\0' ; i++)
printf("%c", t[i]);
printf(" ");
printf(GREEN"%s"GRAY,ep->d_name);	                          //文件名
printf("\n");

close(fd);
}

void myls(int argc,char *argv[])
{
int flag = 0,count = 0;
DIR *p;
struct dirent *ep;

flag = mygetopt(argc,argv);
if(-1 == flag)
{
printf("Agument error!\n");
exit(-1);
}

if(argc>1&&(argv[1][0]!='-'))
{
chdir(argv[1]);
}

if((p=opendir("."))==NULL)
{
perror("opendir");
exit(-1);
}

while((ep=readdir(p))!=NULL)
{
if(0 == flag)
{
if(ep->d_name[0]=='.')
continue;
printf(GREEN"%s"GRAY,ep->d_name);
printf(" ");
}
else if(2 == flag)
{
printf(GREEN"%s"GRAY,ep->d_name);
printf(" ");
}
else if(1 == flag)
{
if(ep->d_name[0]=='.')
continue;
myls_l(ep);
}
else if(3 == flag)
{
myls_l(ep);
}
else
exit(-1);
count++;

}

if(1 != flag && 3 != flag)
printf("\n");
else printf("Total : %d\n",count);

closedir(p);
}

int main(int argc,char *argv[])
{
myls(argc,argv);

return 0;
}


 

二、编译一个简易的tree命令程序。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <dirent.h>
#include <string.h>

#define GRAY    "\033[0m"
#define RED     "\033[1m\033[0;31m"
#define GREEN   "\033[1m\033[0;32m"
#define YELLOW  "\033[1m\033[0;33m"
#define BLU     "\033[1m\033[0;34m"
#define MAGENTA "\033[1m\033[0;35m"
#define CYAN    "\033[1m\033[0;36m"
#define WHITE   "\033[1m\033[0;37m"

void mytree(char *dir,int depth )
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;

if((dp = opendir(dir)) == NULL)
{
perror("Opendir");
exit(-1);
}

chdir(dir);

while((entry = readdir(dp)) != NULL)
{
lstat(entry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode))
{
if(strcmp(".",entry->d_name) == 0 ||
strcmp("..",entry->d_name) == 0)
continue;
printf("%*s%s/\n",depth,"",entry->d_name); //缩进显示
mytree(entry->d_name,depth+4);         //递归遍历
}
else printf(BLU"%*s%s\n"GRAY,depth,"",entry->d_name);
}
chdir("..");
closedir(dp);
}

int main(int argc,char *argv[])
{
if(argc == 1)
mytree("./",0);
else if(argc == 2)
mytree(argv[1],0);
else
printf("Argument error!\n");

return 0;
}


 

三、库

库有静态库和动态库(共享库)两种,其实也很好理解,静态库就是在编译程序的时候把库文件编译到目标文件中,动态库就是在运行的时才载入。

1.如何创建静态库?

创建静态库使用ar命令,它将多个.o文件转换成.a文件,即静态库的后缀名是.a。

例:

ar crs libmyhello.a hello1.o hello2.o hello3.o

使用静态链接库。

gcc -o hello main.c -L. -lmyhello

静态库文件有一个规范法的命名规则,以lib为前缀,紧接着静态库名。因此可以使用上一种命令链接静态库,但需要注意的是-L后接路径,如果为当前路径就是.,-l后接静态库名。当然也可以使用另一种方式链接静态库。

gcc -o hello main.c libmyhello.a 

2.如何创建动态库?

使用gcc创建动态库

gcc -fPIC -c hello.c      //生产.o文件

gcc -shared -o libmyhello.so hello.o

动态库的命名规则同静态库,其后缀为.so,链接动态库的方式与链接静态库的方式相似。但链接后运行程序时,程序不知道动态库文件的位置,因此得考虑动态库的路径问题。

3.动态库路径问题。

为了让执行程序顺利找到动态库,有三种方法。

(1)把库文件拷贝到/usr/lib和/lib目录下。

(2)在LD_LIBRARY_PATH环境变量中添加库文件的路径。

(3)在/etc/ld.so.conf.d/目录下添加一个后缀为.conf的文件,把库文件的路径添加到文件中,并执行ldconfig刷新即可。

973c
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: