存档在 ‘Linux下C编程’ 分类

实现自己的ls命令(上)

2010年6月19日

如果你跟我一样是linux下C编程的初学者,那么动手实现一些linux命令是十分有必要的。本文为你所描述的是常用ls命令。ls命令有众多选项,本文中所描述的my_ls.c程序仅实现了-l和-a选项。

ls命令加入-l选项可以使每个文件单独成一行,并且显示文件的属性。比如:

edsionte@edsionte-laptop:~/code$ ls -l
总用量 232
-rwxr-xr-x 1 edsionte edsionte  9530 2010-06-18 11:26 error
-rw-r--r-- 1 edsionte edsionte   756 2010-06-19 14:39 error.c
-rw-r--r-- 1 edsionte edsionte   755 2010-06-18 11:32 error.c~
-rw------- 1 edsionte edsionte     0 2010-06-16 12:40 example_62.c

ls命令加入-a选项可以显示隐藏文件。linux中隐藏文件是以 . 开头的。比如:

edsionte@edsionte-laptop:~/code$ ls -a
.             example_65.c    my_cdvc       my_mv
..            example_68_1.c  my_cdvc.c     my_mv.c

.表示当前目录,..表示当前目录的父目录。

当然这两个选项可以同时使用,比如:

edsionte@edsionte-laptop:~/code$ ls -al
总用量 240
drwxr-xr-x  3 edsionte edsionte  4096 2010-06-20 12:10 .
drwxr-xr-x 46 edsionte edsionte  4096 2010-06-20 12:10 ..
-rwxr-xr-x  1 edsionte edsionte  9530 2010-06-18 11:26 error
-rw-r--r--  1 edsionte edsionte   756 2010-06-19 14:39 error.c
-rw-r--r--  1 edsionte edsionte   755 2010-06-18 11:32 error.c~
-rw-------  1 edsionte edsionte     0 2010-06-16 12:40 example_62.c
edsionte@edsionte-laptop:~/code$ ls -l -a
总用量 240
drwxr-xr-x  3 edsionte edsionte  4096 2010-06-20 12:10 .
drwxr-xr-x 46 edsionte edsionte  4096 2010-06-20 12:10 ..
-rwxr-xr-x  1 edsionte edsionte  9530 2010-06-18 11:26 error
-rw-r--r--  1 edsionte edsionte   756 2010-06-19 14:39 error.c

本文所述的my_ls.c程序就要实现这种功能。在了解本程序中所有函数之前,请先看一下本程序的流程图:点这里(本blog上传图片有点问题,正在解决中……)。

现在对本程序中的各个函数做以大致说明。

(1)void my_err(const char*,int,int);和void my_err2(const char*,int);

错误捕获函数。详细实现过程请点这里

(2)void display_dir(int flag_param,char*path);

如果命令中含有目录,则进入此函数。此函数将获取path目录下的文件总数以及所有文件名(包括隐藏文件)。流程图点这里

(3)void display(int flag,char*pathname);

pathname是一个文件的完整路径名,本函数首先从完整的路径名中解析出文件名,再根据flag进入不同的函数。流程图点这里

(4)void display_single(char*);

如果参数中不含任何选项或者仅含-a,则进入此函数。本函数直接显示出目录下的所有文件名,并且实现文件名左对齐。

(5)void display_attribute(struct stat,char*);

如果命令中含有-l则进入本函数,显示出文件的各种属性。

在本文的上班部分中主要为您理清本程序的大体结构,在下半部分中将详细分析源代码。

linux下C编程错误捕获函数

2010年6月17日

本文中的错误是指在代码编译完全正确程序可运行的情况下,因为没有成功调用程序中的某些系统调用函数而产生的错误。往往这些系统调用函数通过返回值(比如1,0,-1)来说明其是否调用成功,而程序员需要知道详细的错误信息,因此自建错误捕获函数很有必要。

(1)errno和strerror()

errno它是一个整形的错误代码。当发生错误的时候,系统自动将错误代码赋给errno。使用下面的方法可以获得具体的错误描述:

void my_err(int error)
{
	printf("error:  %s with errno: %d\n",strerror(error),error);
	exit(1);
}

int main()
{
	        ..............
		my_err(errno);
		..............

}

其中char *strerror(int errnum);是通过errnum来获取错误描述,errnum即所传递的errno。该函数末尾的exit(1)使得程序发生错误时退出。但应该包含库函数stdlib.h。

下面进行测试,测试程序(源代码在本文末尾。)使用open()函数创建文件,因为要创建的文件已存在,而且使用了O_EXCL参数,因此open()会产生错误。结果如下:

edsionte@edsionte-laptop:~/code$ ./error
error:   File exists with errno: 17

该方法可以详细显示错误信息以及错误代码。但不能显示错误出现的行数。

(2)perror()

其函数原型为:void perror(const char *s)。s一般是函数名。该函数会先将函数名打印出来,然后再打印出错误信息。错误信息与errno相对应。第二个参数__LINE__是一个宏,表示当前的行数。使用方法:

void my_err2(const char* err_string,int line)
{
	fprintf(stderr,"error:  line:%d ",line);
	perror(err_string);
        exit(1);
}
}

int main()
{
	        .................
		my_err2("open",__LINE__);
                ................

}

测试结果如下:

edsionte@edsionte-laptop:~/code$ ./error
error:  line:29 open: File exists
}

该方法可以显示错误信息以及错误出现的行数。

以上方法是在《linux C编程》中常用的方法,我适当的作了小调整。现在将这两种方法结合起来:

void my_err3(const char* err_string,int line,int error)
{
	printf("error:  line:%d %s():%s with errno:%d\n",line,err_string,strerror(error),error);
        exit(1);
}

int main()
{
	        ................
		my_err3("open",__LINE__,errno);
	        ................

}

测试结果如下:

edsionte@edsionte-laptop:~/code$ ./error
error:  line:30 open():File exists with errno:17

这样就可以显示错误代码,错误描述,错误出现的行数以及出现错误的函数。对于和我一样的新手来说,这里特别要注意的是宏__LINE__前后的那个横线是两个连续的下划线,而不是_LINE_,否则会出现错误。
源代码如下:
说明:本程序只作测试用,为了同时显示三种错误捕获函数的信息,因此屏蔽了每个函数的exit(1)。另外本文头文件函数用“”是因为显示问题,没有什么特别意义。

#include "errno.h"
#include "fcntl.h"
#include "unistd.h"
#include "stdlib.h"
#include "stdio.h
#include "sys/types.h"
#include "sys/stat.h"
#include "string.h"

void my_err(int error)
{
	printf("error:  %s with errno: %d\n",strerror(error),error);
//	exit(1);
}
void my_err2(const char* err_string,int line)
{
	fprintf(stderr,"error:  line:%d ",line);
	perror(err_string);
//	exit(1);
}
void my_err3(const char* err_string,int line,int error)
{
	printf("error:  line:%d %s():%s with errno:%d\n",line,err_string,strerror(error),error);
//      exit(1);
}
int main()
{
	int fd;
	if((fd=open("example_test.c",O_CREAT|O_EXCL,S_IRUSR|S_IWUSR))==-1)
	{
		my_err(errno);
		my_err2("open",__LINE__);
		my_err3("open",__LINE__,errno);
	}
	close(fd);
	return 0;
}

create()和open()

2010年6月9日

creat()和open()都可以创建文件,但是稍有区别。如果按照如下方式设置参数则两者是等价的:

open(const char* pathname, (O_CREAT|O_WRONLY|O_TRUNC),mode_t mode);
creat(const char* pathname,mode_t mode);

若要创建的文件不存在,则按照mode方式创建新文件。当要创建的文件已经存在到时候,覆盖原有文件。事实上是因为O_WRONLY|O_TRUNC参数的原因:当文件存在并且以可写方式打开的时候,原有文件到长度则清0,即会清空原有文件,但是文件属性不变,与原有文件方式相同,并不会设置成mode方式。

在下面的源代码中,以open函数方式创建文件时,由于设置拉O_CREAT|O_EXCL参数,当要创建到文件不存在时,open函数创建这个文件,并且文件到存取权限为S_IRUSR|S_IWUSR。当文件存在时因为设置拉O_EXCL则出现错误。而当以creat()方式创建文件时,如本文开头所述,无论是否存在将要创建的那个文件,都不会出现错误。

下面作测试。

首先注意,在下面的源代码中open()函数中的文件权限s设置为:S_IRUSR|S_IWUSR(文件所有着可读可写)。creat()设置的文件权限为:S_IRWXU(文件所有者可读可写可执行)。

第一次运行本程序,选择使用open()创建example_62.c。

please select a way of creating files:
1.creat 2.open
2
create file success
edsionte@edsionte-laptop:~/code$ ls -l
总用量 48
-rw------- 1 edsionte edsionte    0 2010-06-16 12:38 example_62.c

第二次运行本程序,以creat()创建文件,依然会运行成功,但是此时的example_62.c的存取权限是否是creat()中设置的S_IRWXU呢?

edsionte@edsionte-laptop:~/code$ ./my_create
please select a way of creating files:
1.creat 2.open
1
create file success
edsionte@edsionte-laptop:~/code$ ls -l
总用量 48
-rw------- 1 edsionte edsionte    0 2010-06-16 12:40 example_62.c

正如上面所述的,creat()创建已存在的文件,并不会更改原文件的属性。

源代码如下:

#include "stdio.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "unistd.h"
#include "error.h"

int main()
{
	int fd,n;
	printf("please select a way of creating files:\n");
	printf("1.creat 2.open\n");
	scanf("%d",&n);
	if(n==1)
	{
		if((fd=creat("example_62.c",S_IRWXU))==-1)
		{
			perror("open");
			exit(1);
		}
		else
		{
			printf("create file success\n");
		}
	}
	else if(n==2)
	{
		if((fd=open("example_62.c",O_CREAT|O_EXCL,S_IRUSR|S_IWUSR))==-1)
		{
			perror("open");
			exit(1);
		}
		else
		{
			printf("create file success\n");
		}
	}
	else
	{
		printf("your choice may be wrong\n");
	}
	close(fd);
	return 0;
}

create()和open()是文件操作中最基本的函数,大家应该在实践中不断总结。

windows 7 ultimate product key

windows 7 ultimate product key

winrar download free

winrar download free

winzip registration code

winzip registration code

winzip free download

winzip free download

winzip activation code

winzip activation code

windows 7 key generator

windows 7 key generator

winzip freeware

winzip freeware

winzip free download full version

winzip free download full version

free winrar download

free winrar download

free winrar

free winrar

windows 7 crack

windows 7 crack

windows xp product key

windows xp product key

windows 7 activation crack

windows7 activation crack

free winzip

free winzip

winrar free download

winrar free download

winrar free

winrar free

download winrar free

download winrar free

windows 7 product key

windows 7 product key