Unix第一次实验报告(编程实现程序list.c,列表普通磁盘文件等)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Unix编程实验报告
班级:CCCCCCCC
学号:XXXXXXX
姓名:XXX
一、实验目的
练习vi,使用UNIX的系统调用和库函数,体会UNIX文件通配符的处理方式以及命令对选项的处理方式。

二、实验要求
编程实现程序list.c,列表普通磁盘文件(不考虑目录和设备文件等),列出文件名和文件大小。

a)与ls命令类似,命令行参数可以有0到多个
i.0个参数:列出当前目录下所有文件
ii.参数为普通文件:列出文件
iii.参数为目录:列出目录下所有文件
b)实现自定义选项r,a,l,h,m以及--
i.r 递归方式列出子目录
ii. a 列出文件名第一个字符为圆点的普通文件(默认情况下不列出文件名首字符为圆点的文件,即只显示隐藏文件)
iii.l 后跟一整数,限定文件大小的最小值(字节)
iv.h 后跟一整数,限定文件大小的最大值(字节)
v.m 后跟一整数n,限定文件的最近修改时间必须在n天内
vi.-- 显式地终止命令选项分析
三、程序源码
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
/*将char[]转换为数字*/
int sav(char ch[],int l[])
{
int i=0;
l[0]=0;
while(ch[i]!='\0')
if(ch[i]<='9'&&ch[i]>='0')
{
l[0]=10*l[0]+ch[i]-'0';
i++;
}
else
return 0;
return 1;
}
main(int argc, char *argv[])
{
int i,j,k,ret,l=-1,h=-1,m=-1;
char path[30],path1[30];
struct stat st;
DIR *dir; /*定义Dir*/
struct dirent * entry; /*定义Dirent entry*/
int order[7]; /*各个数字代表含义order[1]->r; [2]->a; [3]->l; [4]->h; [5]->m;
[6]->--*/
time_t tp; /*当前时间*/
/*得到当前path*/
for(i = 1; i < argc; i++);
i--;
if(argv[i][0]=='/' && argc!=1)
{
for(j = 0; argv[i][j] != '\0'; j++)
path[j] = argv[i][j];
path[j]='\0';
}
else
{
path[0]='.';
path[1]='\0';
}
/*Get Order*/
for(i=1;i<=6;i++)
order[i]=0;
for(i = 1; i < argc; i++)
{
if(argv[i][0]=='-')
{
if(argv[i][1]=='r')
order[1]=1;
else
if(argv[i][1]=='a')
order[2]=1;
else
if(argv[i][1]=='l')
{
order[3]=1;
i++;
if(i<argc)
if(sav(argv[i],&l)==0) {
printf("Wrong order!\n");
return;
}
}
else
if(argv[i][1]=='h')
{
order[4]=1;
i++;
if(i<argc)
if(sav(argv[i],&h)==0)
{
printf("Wrong order!\n");
return;
}
}
else
if(argv[i][1]=='m')
{
order[5]=1;
i++;
if(i<argc)
if(sav(argv[i],&m)==0)
{
printf("Wrong order!\n"); return;
}
}
else
if(argv[i][1]=='-')
{
order[6]=1;
i=argc+1;
}
else
{
printf("Wrong order!\n"); return;
}
}
}
/*检查order*/
if(order[3]==1 && l==-1)
{
printf("Wrong order!\n");
return;
}
if(order[4]==1 && h==-1)
{
printf("Wrong order!\n");
return;
}
if(order[5]==1 && m==-1)
{
printf("Wrong order!\n");
return;
}
time(&tp);/*获取当前时间*/
ret = stat(path, &st);/*获取信息*/
/*处理order的信息*/
if(ret == 0) /*成功读取path信息*/
{
if(S_ISDIR(st.st_mode)) /*如果是dir*/
{
dir = opendir(path);
if (dir == NULL) /*Unreadable*/
{
printf("Open directory \"%s\": %s (ERROR %d)\n",path, strerror(errno), errno);
return 1;
}
while ((entry = readdir(dir)) != NULL) /*一直读,直至文件结束*/
{
strcpy(path1,path);
strcat(path1, "/");
strcat(path1, entry->d_name);
stat(path1, &st);
if(order[1]==0) /*不是-r*/
{
if(order[2]==1) /*-a*/
{
if(order[3]==1 && order[4]==1) /*-l 和-h*/
{
if((st.st_size<=h) && (st.st_size>=l))
if(order[5]==1){ /*-m*/
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);}
else /*no -m*/
printf("%s \n", entry->d_name);
}
else if(order[3]==1 && order[4]==0)
{
if(st.st_size>=l)
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);}
else
printf("%s \n", entry ->d_name);
}
else if(order[3]==0 && order[4]==1)
{
if(st.st_size<=m)
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);}
else
printf("%s \n", entry->d_name);
}
else if(order[3]==0 && order[4]==0)
{
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);}
else
printf("%s \n", entry->d_name); }
}
else
{
if(order[3]==1 && order[4]==1)
{
if((st.st_size<=h) && (st.st_size>=l) && entry->d_name[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);} else
printf("%s \n", entry->d_name); }
else if(order[3]==1 && order[4]==0)
{
if(st.st_size>=l && entry->d_name[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry-
>d_name);}
else
printf("%s \n", entry->d_name);
}
else if(order[3]==0 && order[4]==1)
{
if(st.st_size<=m && entry->d_name[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);} else
printf("%s \n", entry->d_name);
}
else if(order[3]==0 && order[4]==0)
{
if(entry->d_name[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", entry->d_name);}
else
printf("%s \n", entry->d_name);
}
}
}/*order[1]=0 end*/
}/*while*/
closedir(dir);
}/*is DIR*/
else/*not a dir*/
{
/*Change path into filename*/
for(i=0,j=0;path[i]!='\0';i++)
if(path[i]=='/')
j++;
k=j;
for(j=0,i=0;j<k;i++)
if(path[i]=='/')
j++;
k=i;
for(j=0;path[j+k]!='\0';j++)
path[j]=path[j+k];
path[j]='\0';
/*Deal with the orders, not considering order[1]-->-r*/ if(order[2]==1)
{
if(order[3]==1 && order[4]==1)
{
if((st.st_size<=h) && (st.st_size>=l))
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m) printf("%s \n", path);}
else
printf("%s \n", path);
}
else if(order[3]==1 && order[4]==0)
{
if(st.st_size>=l)
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
else if(order[3]==0 && order[4]==1)
{
if(st.st_size<=m)
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
else if(order[3]==0 && order[4]==0)
{
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
}
else
{
if(order[3]==1 && order[4]==1)
{
if((st.st_size<=h) && (st.st_size>=l) && path[0]!='.') if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
else if(order[3]==1 && order[4]==0)
{
if(st.st_size>=l && path[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
else if(order[3]==0 && order[4]==1)
{
if(st.st_size<=m && path[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
else if(order[3]==0 && order[4]==0)
{
if(path[0]!='.')
if(order[5]==1){
if(((tp-st.st_mtime)/86400+1)<=m)
printf("%s \n", path);}
else
printf("%s \n", path);
}
}
}
}/*path 正确*/
else
{
printf("Wrong path.\n");
}/*path 错误*/
return;
}/*main*/
四、测试结果
(1)./list –l 100 –h 5000 /bin /etc (列出大小在100~5000之间的文件)。

由与上述/bin /etc 下符合条件的文件太多,故只显示首尾部分结果。

(2) ./list –ar -l 50000 –m 2
(递归式列出当前目录树下文件大小超50KB并且2天内修改过的文件(包括文件名首字符为圆点的文件))
(3)./list -- -l
(4)./list *
五、实验总结
通过这次实验练习了在终端通过Vi编辑器编写代码,熟悉了命令模式和编辑模式的转换过程,学会了通过指令在终端直接编译、调试和运行代码。

在实现list 函数功能的过程中遇到了很多问题,但通过对这些问题的研究和解决使我巩固了我对UNIX常用命令的功能的使用。

通过查找各种学习资料,更加深了我对Unix系统运行机制的理解,收获颇丰。

相关文档
最新文档