首页资源分类嵌入式系统Linux > linux系统API

linux系统API

已有 445109个资源

下载专区

文档信息举报收藏

标    签:linux

分    享:

文档简介

一份不错的资料,欢迎点击下载

文档预览

Linux C 函数参考 isalnum(测试字符是否为英文或数字) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isalpha,isdigit,islower,isupper #include int isalnum (int c) 检查参数 c 是否为英文字母或阿拉伯数字,在标准 c 中相当于使用 (isalpha( c )|| isdigit( c ))做测试。 若参数 c 为字母或数字,则返回 TRUE,否则返回 NULL( 0 )。 此为宏定义,非真正函数。 范例 /* 找出 str 字符串中为英文字母或数字的字符 */ #include < ctype.h> main() { char str[]=”123c@#FDsP[e?”; int i; for (i=0;str[i]!=0;i++ ) if ( isalnum(str[i])) printf(“%c is an alphanumeric character\n”,str[i]); } 执行 1 is an apphabetic character 2 is an apphabetic character 3 is an apphabetic character c is an apphabetic character F is an apphabetic character D is an apphabetic character s is an apphabetic character P is an apphabetic character e is an apphabetic character isalpha (测试字符是否为英文字母) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isalnum,islower,isupper #include int isalpha (int c) 检查参数 c 是否为英文字母,在标准 c 中相当于使用 (isupper(c)||islower(c))做测试。 若参数 c 为英文字母,则返回 TRUE,否则返回 NULL( 0 )。 此为宏定义,非真正函数 范例 /* 找出 str 字符串中为英文字母的字符*/ #include main() { char str[]=”123c@#FDsP[e?”; int i; for (i=0;str[i]!=0;i++) if(isalpha(str[i])) printf(“%c is an alphanumeric character\n”,str[i]); } 执行 c is an apphabetic character F is an apphabetic character D is an apphabetic character s is an apphabetic character P is an apphabetic character e is an apphabetic character isascii(测试字符是否为 ASCII 码字符) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 iscntrl #include int isascii(int c); 检查参数 c 是否为 ASCII 码字符,也就是判断 c 的范围是否在 0 到 127 之间。 若参数 c 为 ASCII 码字符,则返回 TRUE,否则返回 NULL ( 0 )。 此为宏定义,非真正函数。 范例 /* 判断 int i 是否具有对映的 ASCII 码字符 */ #include main() { int i; for(i=125;i<130;i++) if(isascii(i)) printf("%d is an ascii character:%c\n",i,i); else printf("%d is not an ascii character\n",i); } 执行 125 is an ascii character:} 126 is an ascii character:~ 127 is an ascii character: 128 is not an ascii character 129 is not an ascii character iscntrl(测试字符是否为 ASCII 码的控制字符) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isascii #include int iscntrl(int c); 检查参数 c 是否为 ASCII 控制码,也就是判断 c 的范围是否在 0 到 30 之间 若参数 c 为 ASCII 控制码,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数。 isdigit(测试字符是否为阿拉伯数字) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isxdigit #include int isdigit(int c) 检查参数 c 是否为阿拉伯数字 0 到 9。 若参数 c 为阿拉伯数字,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数。 范例 /* 找出 str 字符串中为阿拉伯数字的字符 */ #include main() { char str[]="123@#FDsP[e?"; int i; for(i=0;str[i]!=0;i++) if(isdigit(str[i])) printf("%c is an digit character\n",str[i]); } 执行 1 is an digit character 2 is an digit character 3 is an digit character isgraphis(测试字符是否为可打印字符) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isprint #include int isgraph (int c) 检查参数 c 是否为可打印字符,若 c 所对映的 ASCII 码可打印,且 非空格字符则返回 TRUE。 若参数 c 为可打印字符,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数 范例 /* 判断 str 字符串中哪些为可打印字符 */ #include main() { char str[]="a5 @;"; int i; for(i=0;str[i]!=0;i++) if(isgraph(str[i])) printf("str[%d] is printable character:%d\n",i,str[i]); } 执行 str[0] is printable character:a str[1] is printable character:5 str[3] is printable character:@ str[4] is printable character:; islower(测试字符是否为小写字母) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isalpha,isupper #include int islower(int c) 检查参数 c 是否为小写英文字母。 若参数 c 为小写英文字母,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数。 范例 #include main() { char str[]="123@#FDsP[e?"; int i; for(i=0;str[i]!=0;i++) if(islower(str[i])) printf("%c is a lower-case character\n",str[i]); } 执行 c is a lower-case character s is a lower-case character e is a lower-case character isprint(测试字符是否为可打印字符) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isgraph #include int isprint(int c); 检查参数 c 是否为可打印字符,若 c 所对映的 ASCII 码可打印,其 中包含空格字符,则返回 TRUE。 若参数 c 为可打印字符,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数。 范例 /* 判断 str 字符串中哪些为可打印字符 包含空格字符*/ #include main() { char str[]="a5 @;"; int i; for(i=0;str[i]!=0;i++) if(isprint(str[i])) printf("str[%d] is printable character:%d\n",i,str[i]); } 执行 str[0] is printable character:a str[1] is printable character:5 str[2] is printable character: str[3] is printable character:@ str[4] is printable character:; isspace(测试字符是否为空格字符) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isgraph #include int isspace(int c) 检查参数 c 是否为空格字符,也就是判断是否为空格(’’)、定 位 字 符 ( ’ \t’ ) 、 CR ( ’ \r’ ) 、 换 行 ( ’ \n’ ) 、 垂 直 定 位 字 符 (’\v’)或翻页(’\f’)的情况。 若参数 c 为空格字符,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数 范例 /*将字符串 str[]中内含的空格字符找出,并显示空格字符的 ASCII 码*/ #include main() { char str="123c @# FD\tsP[e?\n"; int i; for(i=0;str[i]!=0;i++) if(isspace(str[i])) printf("str[%d] is a white-space character:%d\n",i,str[i]); } 执行 str[4] is a white-space character:32 str[7] is a white-space character:32 str[10] is a white-space character:9 /* \t */ str[16] is a white-space character:10 /* \t */ ispunct(测试字符是否为标点符号或特殊符号) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isspace,isdigit,isalpha #inlude int ispunct (int c) 检查参数 c 是否为标点符号或特殊符号。返回 TRUE 也就是代表参 数 c 为非空格、非数字和非英文字母。 若 参 数 c 为 标 点 符 号 或 特 殊 符 号 , 则 返 回 TRUE , 否 则 返 回 NULL(0)。 此为宏定义,非真正函数 范例 /*列出字符串 str 中的标点符号或特殊符号*/ #include main() { char str[]="123c@ #FDsP[e?"; int i; for(i=0;str[i]!=0;i++) if(ispunct(str[i])) printf("%c\n",str[i]); } 执行 @#[? isupper(测试字符是否为大写英文字母) 相关函数 表头文件 定义函数 isalpha,islower #include int isupper(int c) 函数说明 返回值 附加说明 检查参数 c 是否为大写英文字母。 若参数 c 为大写英文字母,则返回 TRUE,否则返回 NULL(0)。 此为宏定义,非真正函数 范例 /*找出字符串 str 中为大写英文字母的字符*/ #include main() { char str[]="123c@#FDsP[e?"; int i; for(i=0;str[i]!=0;i++) if(isupper(str[i])) printf("%c is an uppercase character\n",str[i]); } 执行 F is an uppercase character D is an uppercase character P is an uppercase character isxdigit(测试字符是否为 16 进制数字) 相关函数 表头文件 定义函数 函数说明 返回值 isalnum,isdigit #include int isxdigit (int c) 检查参数 c 是否为 16 进制数字,只要 c 为下列其中一个情况则返回 TRUE。16 进制数字:0123456789ABCDEF 若参数 c 为 16 进制数字,则返回 TRUE,否则返回 NULL(0)。 附加说明 此为宏定义,非真正函数。 范例 /*找出字符串 str 中为十六进制数字的字符*/ #include main() { char str[]="123c@#FDsP[e?"; int i; for(i=0;str[i]!=0;i++) if(isxdigit(str[i])) printf("%c is a hexadecimal digits\n",str[i]); } 执行 1 is a hexadecimal digits 2 is a hexadecimal digits 3 is a hexadecimal digits c is a hexadecimal digits F is a hexadecimal digits D is a hexadecimal digits e is a hexadecimal digits atof(将字符串转换成浮点型数) 相关函数 表头文件 定义函数 函数说明 atoi,atol,strtod,strtol,strtoul #include double atof(const char *nptr); atof()会扫描参数 nptr 字符串,跳过前面的空格字符,直到遇上 数字或正负符号才开始做转换,而再遇到非数字或字符串结束时 返回值 附加说明 (’\0’)才结束转换,并将结果返回。参数 nptr 字符串可包含正负 号、小数点或 E(e)来表示指数部分,如 123.456 或 123e-2。 返回转换后的浮点型数。 atof()与使用 strtod(nptr,(char**)NULL);结果相同。 范例 /* 将字符串 a 与字符串 b 转换成数字后相加*/ #include main() { char *a=”-100.23”; char *b=”200e-2”; float c; c=atof(a)+atof(b); printf(“c=%.2f\n”,c); } 执行 c=-98.23 atoi(将字符串转换成整型数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 atof,atol,atrtod,strtol,strtoul #include int atoi(const char *nptr); atoi()会扫描参数 nptr 字符串,跳过前面的空格字符,直到遇上数 字或正负符号才开始做转换,而再遇到非数字或字符串结束时(’ \0’)才结束转换,并将结果返回。 返回转换后的整型数。 atoi()与使用 strtol(nptr,(char**)NULL,10);结果相同。 范例 /* 将字符串 a 与字符串 b 转换成数字后相加 */ #include mian() { char a[]=”-100”; char b[]=”456”; int c; c=atoi(a)+atoi(b); printf(c=%d\n”,c); } 执行 c=356 atol(将字符串转换成长整型数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 atof,atoi,strtod,strtol,strtoul #include long atol(const char *nptr); atol()会扫描参数 nptr 字符串,跳过前面的空格字符,直到遇上数 字或正负符号才开始做转换,而再遇到非数字或字符串结束时(’ \0’)才结束转换,并将结果返回。 返回转换后的长整型数。 atol()与使用 strtol(nptr,(char**)NULL,10);结果相同。 范例 /*将字符串 a 与字符串 b 转换成数字后相加*/ #include main() { char a[]=”1000000000”; char b[]=” 234567890”; long c; c=atol(a)+atol(b); printf(“c=%d\n”,c); } 执行 c=1234567890 gcvt(将浮点型数转换为字符串,取四舍五入) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 ecvt,fcvt,sprintf #include char *gcvt(double number,size_t ndigits,char *buf); gcvt()用来将参数 number 转换成 ASCII 码字符串,参数 ndigits 表示 显示的位数。gcvt()与 ecvt()和 fcvt()不同的地方在于,gcvt()所转换 后的字符串包含小数点或正负符号。若转换成功,转换后的字符串 会放在参数 buf 指针所指的空间。 返回一字符串指针,此地址即为 buf 指针。 范例 #include main() { double a=123.45; double b=-1234.56; char *ptr; int decpt,sign; gcvt(a,5,ptr); printf(“a value=%s\n”,ptr); ptr=gcvt(b,6,ptr); printf(“b value=%s\n”,ptr); } 执行 a value=123.45 b value=-1234.56 strtod(将字符串转换成浮点数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 atoi,atol,strtod,strtol,strtoul #include double strtod(const char *nptr,char **endptr); strtod()会扫描参数 nptr 字符串,跳过前面的空格字符,直到遇上数 字或正负符号才开始做转换,直到出现非数字或字符串结束时(’ \0’)才结束转换,并将结果返回。若 endptr 不为 NULL,则会将遇 到不合条件而终止的 nptr 中的字符指针由 endptr 传回。参数 nptr 字 符串可包含正负号、小数点或 E(e)来表示指数部分。如 123.456 或 123e-2。 返回转换后的浮点型数。 参考 atof()。 范例 /*将字符串 a,b,c 分别采用 10,2,16 进制转换成数字*/ #include mian() { char a[]=”1000000000”; char b[]=”1000000000”; char c[]=”ffff”; printf(“a=%d\n”,strtod(a,NULL,10)); printf(“b=%d\n”,strtod(b,NULL,2)); printf(“c=%d\n”,strtod(c,NULL,16)); } 执行 a=1000000000 b=512 c=65535 strtol(将字符串转换成长整型数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 atof,atoi,atol,strtod,strtoul #include long int strtol(const char *nptr,char **endptr,int base); strtol()会将参数 nptr 字符串根据参数 base 来转换成长整型数。参 数 base 范围从 2 至 36,或 0。参数 base 代表采用的进制方式,如 base 值为 10 则采用 10 进制,若 base 值为 16 则采用 16 进制等。当 base 值为 0 时则是采用 10 进制做转换,但遇到如’0x’前置字符则 会使用 16 进制做转换。一开始 strtol()会扫描参数 nptr 字符串, 跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,再 遇到非数字或字符串结束时(‘\0’)结束转换,并将结果返回。若参数 endptr 不为 NULL,则会将遇到不合条件而终止的 nptr 中的字符指 针由 endptr 返回。 返回转换后的长整型数,否则返回 ERANGE 并将错误代码存入 errno 中。 ERANGE 指定的转换字符串超出合法范围。 范例 /* 将字符串 a,b,c 分别采用 10,2,16 进制转换成数字*/ #include main() { char a[]=”1000000000”; char b[]=”1000000000”; char c[]=”ffff”; printf(“a=%d\n”,strtol(a,NULL,10)); printf(“b=%d\n”,strtol(b,NULL,2)); printf(“c=%d\n”,strtol(c,NULL,16)); } 执行 a=1000000000 b=512 c=65535 strtoul(将字符串转换成无符号长整型数) 相关函数 atof,atoi,atol,strtod,strtol 表头文件 定义函数 函数说明 返回值 附加说明 范例 参考 strtol() #include unsigned long int strtoul(const char *nptr,char **endptr,int base); strtoul()会将参数 nptr 字符串根据参数 base 来转换成无符号的长整 型数。参数 base 范围从 2 至 36,或 0。参数 base 代表采用的进制方 式,如 base 值为 10 则采用 10 进制,若 base 值为 16 则采用 16 进制 数等。当 base 值为 0 时则是采用 10 进制做转换,但遇到如’0x’前 置字符则会使用 16 进制做转换。一开始 strtoul()会扫描参数 nptr 字符串,跳过前面的空格字符串,直到遇上数字或正负符号才开始 做转换,再遇到非数字或字符串结束时(’\0’)结束转换,并将结 果返回。若参数 endptr 不为 NULL,则会将遇到不合条件而终止的 nptr 中的字符指针由 endptr 返回。 返回转换后的长整型数,否则返回 ERANGE 并将错误代码存入 errno 中。 ERANGE 指定的转换字符串超出合法范围。 toascii(将整型数转换成合法的 ASCII 码字符) 相关函数 表头文件 定义函数 函数说明 返回值 isascii,toupper,tolower #include int toascii(int c) toascii()会将参数 c 转换成 7 位的 unsigned char 值,第八位则会 被清除,此字符即会被转成 ASCII 码字符。 将转换成功的 ASCII 码字符值返回。 范例 #include main() { int a=217; char b; printf(“before toascii () : a value =%d(%c)\n”,a,a); b=toascii(a); printf(“after toascii() : a value =%d(%c)\n”,b,b); } 执行 before toascii() : a value =217() after toascii() : a value =89(Y) tolower(将大写字母转换成小写字母) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 isalpha,toupper #include int tolower(int c); 若参数 c 为大写字母则将该对应的小写字母返回。 返回转换后的小写字母,若不须转换则将参数 c 值返回。 范例 /* 将 s 字符串内的大写字母转换成小写字母*/ #include main() { char s[]=”aBcDeFgH12345;!#$”; int i; printf(“before tolower() : %s\n”,s); for(i=0;I int toupper(int c); 若参数 c 为小写字母则将该对映的大写字母返回。 返回转换后的大写字母,若不须转换则将参数 c 值返回。 范例 /* 将 s 字符串内的小写字母转换成大写字母 */ #include main() { char s[]=”aBcDeFgH12345;!#$”; int i; printf(“before toupper() : %s\n”,s); for(i=0;I void *calloc(size_t nmemb,size_t size); 函数说明 返回值 calloc()用来配置 nmemb 个相邻的内存单位,每一单位的大小为 size,并返回指向第一个元素的指针。这和使用下列的方式效果相同: malloc(nmemb* size);不过,在利用 calloc()配置内存时会将内存内 容初始化为 0。 若配置成功则返回一指针,失败则返回 NULL。 范例 /* 动态配置 10 个 struct test 空间 */ #include struct test { int a[10]; char b[20]; } main() { struct test *ptr=calloc(sizeof(struct test),10); } free(释放原先配置的内存) 相关函数 表头文件 定义函数 函数说明 malloc,calloc,realloc,brk #include void free(void *ptr); 参数 ptr 为指向先前由 malloc()、calloc()或 realloc()所返回的内存 指针。调用 free()后 ptr 所指的内存空间便会被收回。假若参数 ptr 所 指的内存空间已被收回或是未知的内存地址,则调用 free()可能会 有无法预期的情况发生。若参数 ptr 为 NULL,则 free()不会有任何 作用。 getpagesize(取得内存分页大小) 相关函数 sbrk 表头文件 定义函数 函数说明 返回值 附加说明 #include size_t getpagesize(void); 返回一分页的大小,单位为字节(byte)。此为系统的分页大小, 不一定会和硬件分页大小相同。 内存分页大小。 在 Intel x86 上其返回值应为 4096bytes。 范例 #include main() { printf(“page size = %d\n”,getpagesize( ) ); } malloc(配置内存空间) 相关函数 表头文件 定义函数 函数说明 返回值 calloc,free,realloc,brk #include void * malloc(size_t size); malloc()用来配置内存空间,其大小由指定的 size 决定。 若配置成功则返回一指针,失败则返回 NULL。 范例 void p = malloc(1024); /*配置 1k 的内存*/ mmap(建立内存映射) 相关函数 munmap,open 表头文件 定义函数 函数说明 返回值 错误代码 #include #include void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offsize); mmap()用来将某个文件内容映射到内存中,对该内存区域的存取 即是直接对该文件内容的读写。 参数 start 指向欲对应的内存起始地址,通常设为 NULL,代表让系 统自动选定地址,对应成功后该地址会返回。参数 length 代表将文 件中多大的部分对应到内存。参数 prot 代表映射区域的保护方式, 有下列组合: PROT_EXEC 映射区域可被执行 PROT_READ 映射区域可被读取 PROT_WRITE 映射区域可被写入 PROT_NONE 映射区域不能存取 参数 flags 会影响映射区域的各种特性: MAP_FIXED 如果参数 start 所指的地址无法成功建立映射时, 则放弃映射,不对地址做修正。通常不鼓励用此 旗标。 MAP_SHARED 对映射区域的写入数据会复制回文件内,而且 允许其他映射该文件的进程共享。 MAP_PRIVATE 对映射区域的写入操作会产生一个映射文件的 复 制 , 即 私 人 的 “ 写 入 时 复 制 ” ( copy on write) 对此区域作的任何修改都不会写回原来的文 件内容。 MAP_ANONYMOUS 建立匿名映射。此时会忽略参数 fd,不涉 及文件,而且映射区域无法和其他进程共 享。 MAP_DENYWRITE 只允许对映射区域的写入操作,其他对文件 直接写入的操作将会被拒绝。 MAP_LOCKED 将映射区域锁定住,这表示该区域不会被置换 (swap)。 在调用 mmap()时必须要指定 MAP_SHARED 或 MAP_PRIVATE。参 数 fd 为 open()返回的文件描述词,代表欲映射到内存的文件。参数 offset 为文件映射的偏移量,通常设置为 0,代表从文件最前方开 始对应,offset 必须是分页大小的整数倍。 若映射成功则返回映射区的内存起始地址,否则返回 MAP_FAILED(-1),错误原因存于 errno 中。 EBADF 参数 fd 不是有效的文件描述词 EACCES 存取权限有误。如果是 MAP_PRIVATE 情况下文件必须 可读,使用 MAP_SHARED 则要有 PROT_WRITE 以及 该文件要能写入。 EINVAL 参数 start、length 或 offset 有一个不合法。 EAGAIN 文件被锁住,或是有太多内存被锁住。 ENOMEM 内存不足。 范例 /* 利用 mmap()来读取/etc/passwd 文件内容*/ #include #include #include #include #include main() { int fd; void *start; struct stat sb; fd=open(“/etc/passwd”,O_RDONLY); /*打开/etc/passwd*/ fstat(fd,&sb); /*取得文件大小*/ start=mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,fd,0); if(start= = MAP_FAILED) /*判断是否映射成功*/ return; printf(“%s”,start); munma(start,sb.st_size); /*解除映射*/ closed(fd); } 执行 root : x : 0 : root : /root : /bin/bash bin : x : 1: 1 : bin : /bin : daemon : x : 2 : 2 :daemon : /sbin adm : x : 3 : 4 : adm : /var/adm : lp : x :4 :7 : lp : /var/spool/lpd : sync : x : 5 : 0 : sync : /sbin : bin/sync : shutdown : x : 6 : 0 : shutdown : /sbin : /sbin/shutdown halt : x : 7 : 0 : halt : /sbin : /sbin/halt mail : x : 8 : 12 : mail : /var/spool/mail : news : x :9 :13 : news : /var/spool/news : uucp : x :10 :14 : uucp : /var/spool/uucp : operator : x : 11 : 0 :operator : /root: games : x : 12 :100 : games :/usr/games: gopher : x : 13 : 30 : gopher : /usr/lib/gopher-data: ftp: x :14 :50 : FTP User: /home/ftp: nobody : x :99: 99: Nobody : /: xfs :x :100 :101 : X Font Server : /etc/xll/fs : /bin/false gdm : x : 42 :42 : : /home/gdm: /bin/bash kids : x : 500 :500 :/home/kids : /bin/bash munmap(解除内存映射) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 mmap #include #include int munmap(void *start,size_t length); munmap()用来取消参数 start 所指的映射内存起始地址,参数 length 则是欲取消的内存大小。当进程结束或利用 exec 相关函数来执行其 他程序时,映射内存会自动解除,但关闭对应的文件描述词时不会 解除映射。 如果解除映射成功则返回 0,否则返回-1,错误原因存于 errno 中 EINVAL 参数 start 或 length 不合法。 范例 参考 mmap() asctime(将时间和日期以字符串格式表示) 相关函数 表头文件 time,ctime,gmtime,localtime #include 定义函数 函数说明 返回值 附加说明 char * asctime(const struct tm * timeptr); asctime()将参数 timeptr 所指的 tm 结构中的信息转换成真实世界 所使用的时间日期表示方法,然后将结果以字符串形态返回。此函 数已经由时区转换成当地时间,字符串格式为: “Wed Jun 30 21:49:08 1993\n” 若再调用相关的时间日期函数,此字符串可能会被破坏。此函数与 ctime 不同处在于传入的参数是不同的结构。 返回一字符串表示目前当地的时间日期。 范例 #include main() { time_t timep; time (&timep); printf(“%s”,asctime(gmtime(&timep))); 执行 Sat Oct 28 02:10:06 2000 ctime(将时间和日期以字符串格式表示) 相关函数 表头文件 定义函数 函数说明 time,asctime,gmtime,localtime #include char *ctime(const time_t *timep); ctime()将参数 timep 所指的 time_t 结构中的信息转换成真实世界 所使用的时间日期表示方法,然后将结果以字符串形态返回。此函 数已经由时区转换成当地时间,字符串格式为“Wed Jun 30 21 :49 08 1993\n”。若再调用相关的时间日期函数,此字符串可能会被破坏。 返回值 返回一字符串表示目前当地的时间日期。 范例 #include main() { time_t timep; time (&timep); printf(“%s”,ctime(&timep)); } 执行 Sat Oct 28 10 : 12 : 05 2000 gettimeofday(取得目前的时间) 相关函数 表头文件 定义函数 函数说明 time,ctime,ftime,settimeofday #include #include int gettimeofday ( struct timeval * tv , struct timezone * tz ) gettimeofday () 会把目前的时间有 tv 所指的结构返回,当地时区 的信息则放到 tz 所指的结构中。timeval 结构定义为: struct timeval{ long tv_sec; /*秒*/ long tv_usec; /*微秒*/ }; timezone 结构定义为: struct timezone{ int tz_minuteswest; /*和 Greenwich 时间差了多少分钟*/ int tz_dsttime; /*日光节约时间的状态*/ }; 上述两个结构都定义在 /usr/include/sys/time.h。tz_dsttime 所代表 的状态如下: DST_NONE /*不使用*/ DST_USA /*美国*/ DST_AUST /*澳洲*/ 返回值 附加说明 DST_WET /*西欧*/ DST_MET /*中欧*/ DST_EET /*东欧*/ DST_CAN /*加拿大*/ DST_GB /*大不列颠*/ DST_RUM /*罗马尼亚*/ DST_TUR /*土耳其*/ DST_AUSTALT /*澳洲(1986 年以后)*/ 成功则返回 0,失败返回-1,错误代码存于 errno。 EFAULT 指针 tv 和 tz 所指的内存空间超出存取权限。 范例 #include #include main(){ struct timeval tv; struct timezone tz; gettimeofday (&tv , &tz); printf(“tv_sec; %d\n”, tv,.tv_sec) ; printf(“tv_usec; %d\n”,tv.tv_usec); printf(“tz_minuteswest; %d\n”, tz.tz_minuteswest); printf(“tz_dsttime, %d\n”,tz.tz_dsttime); } 执行 tv_sec: 974857339 tv_usec:136996 tz_minuteswest:-540 tz_dsttime:0 gmtime(取得目前时间和日期) 相关函数 表头文件 time,asctime,ctime,localtime #include 定义函数 struct tm*gmtime(const time_t*timep); 函数说明 gmtime()将参数 timep 所指的 time_t 结构中的信息转换成真实世界 所使用的时间日期表示方法,然后将结果由结构 tm 返回。结构 tm 的定义为: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; }; int tm_sec 代表目前秒数,正常范围为 0-59,但允许至 61 秒 int tm_min 代表目前分数,范围 0-59 int tm_hour 从午夜算起的时数,范围为 0-23 int tm_mday 目前月份的日数,范围 01-31 int tm_mon 代表目前月份,从一月算起,范围从 0-11 int tm_year 从 1900 年算起至今的年数 int tm_wday 一星期的日数,从星期一算起,范围为 0-6 int tm_yday 从今年 1 月 1 日算起至今的天数,范围为 0-365 int tm_isdst 日光节约时间的旗标 此函数返回的时间日期未经时区转换,而是 UTC 时间。 返回值 返回结构 tm 代表目前 UTC 时间 范例 #include main(){ char *wday[]={“Sun”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”,”Sat” }; time_t timep; struct tm *p; time(&timep); p=gmtime(&timep); printf(“%d%d%d”,(1900+p->tm_year), (1+p->tm_mon),p->tm_mday); printf(“%s%d;%d;%d\n”, wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec); } 执行 2000/10/28 Sat 8:15:38 localtime(取得当地目前时间和日期) 相关函数 表头文件 定义函数 函数说明 返回值 time, asctime, ctime, gmtime #include struct tm *localtime(const time_t * timep); localtime()将参数 timep 所指的 time_t 结构中的信息转换成真实世 界所使用的时间日期表示方法,然后将结果由结构 tm 返回。结构 tm 的定义请参考 gmtime()。此函数返回的时间日期已经转换成当地 时区。 返回结构 tm 代表目前的当地时间。 范例 #include main(){ char *wday[]={“Sun”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”,”Sat”}; time_t timep; struct tm *p; time(&timep); p=localtime(&timep); /*取得当地时间*/ printf (“%d%d%d ”, (1900+p->tm_year),( l+p->tm_mon), p->tm_mday); printf(“%s%d:%d:%d\n”, wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec); } 执行 2000/10/28 Sat 11:12:22 mktime(将时间结构数据转换成经过的秒数) 相关函数 表头文件 time,asctime,gmtime,localtime #include 定义函数 函数说明 返回值 time_t mktime(strcut tm * timeptr); mktime()用来将参数 timeptr 所指的 tm 结构数据转换成从公元 1970 年 1 月 1 日 0 时 0 分 0 秒算起至今的 UTC 时间所经过的秒数。 返回经过的秒数。 范例 /* 用 time()取得时间(秒数),利用 localtime() 转换成 struct tm 再利用 mktine()将 struct tm 转换成原来的秒数 */ #include main() { time_t timep; strcut tm *p; time(&timep); printf(“time() : %d \n”,timep); p=localtime(&timep); timep = mktime(p); printf(“time()->localtime()->mktime():%d\n”,timep); } 执行 time(): 974943297 time()->localtime()->mktime():974943297 settimeofday(设置目前时间) 相关函数 表头文件 定义函数 函数说明 返回值 time,ctime,ftime,gettimeofday #include #include int settimeofday ( const struct timeval *tv,const struct timezone *tz); settimeofday()会把目前时间设成由 tv 所指的结构信息,当地时 区信息则设成 tz 所指的结构。详细的说明请参考 gettimeofday()。 注意,只有 root 权限才能使用此函数修改时间。 成功则返回 0,失败返回-1,错误代码存于 errno。 错误代码 EPERM 并非由 root 权限调用 settimeofday(),权限不够。 EINVAL 时区或某个数据是不正确的,无法正确设置时间。 time(取得目前的时间) 相关函数 表头文件 定义函数 ctime,ftime,gettimeofday #include time_t time(time_t *t); 函数说明 返回值 此函数会返回从公元 1970 年 1 月 1 日的 UTC 时间从 0 时 0 分 0 秒 算起到现在所经过的秒数。如果 t 并非空指针的话,此函数也会将 返回值存到 t 指针所指的内存。 成功则返回秒数,失败则返回(( time_t)-1)值,错误原因存于 errno 中。 范例 #include mian() { int seconds= time((time_t*)NULL); printf(“%d\n”,seconds); } 执行 972699100 bcmp(比较内存内容) 相关函数 表头文件 定义函数 函数说明 bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp #include int bcmp ( const void *s1,const void * s2,int n); bcmp()用来比较 s1 和 s2 所指的内存区间前 n 个字节,若参数 n 为 0,则返回 0。 返回值 附加说明 若参数 s1 和 s2 所指的内存内容都完全相同则返回 0 值,否则返回 非零值。 建议使用 memcmp()取代。 范例 参考 memcmp()。 bcopy(拷贝内存内容) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 memccpy,memcpy,memmove,strcpy,ctrncpy #include void bcopy ( const void *src,void *dest ,int n); bcopy()与 memcpy()一样都是用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指的地址,不过参数 src 与 dest 在传给函数时是相 反的位置 无 建议使用 memcpy()取代 范例 #include main() { char dest[30]=”string(a)”; char src[30]=”string\0string”; int i; bcopy(src,dest,30);/* src 指针放在前*/ printf(bcopy(): “) for(i=0;i<30;i++) printf(“%c”,dest[i]); memcpy(dest src,30); /*dest 指针放在钱*/ printf(‘\nmemcpy() : “); for(i=0;i<30;i++) printf(“%c”,dest[i]); 执行 bcopy() : string string memcpy() :string sring bzero(将一段内存内容全清为零) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 memset,swab #include void bzero(void *s,int n); bzero()会将参数 s 所指的内存区域前 n 个字节,全部设为零值。 相当于调用 memset((void *)s,0,size_t n); 无 建议使用 memset 取代 范例 参考 memset()。 index(查找字符串中第一个出现的指定字符) 相关函数 表头文件 定义函数 函数说明 返回值 rindex,srechr,strrchr #include char * index( const char *s, int c); index()用来找出参数 s 字符串中第一个出现的参数 c 地址,然后 将该字符出现的地址返回。字符串结束字符( NULL)也视为字符 串一部分。 如果找到指定的字符则返回该字符所在地址,否则返回 0。 范例 #include main() { char *s =”0123456789012345678901234567890”; char *p; p =index(s,’5’); printf(%s\n”,p); } 执行 56789012345678901234567890 memccpy(拷贝内存内容) 相关函数 bcopy,memcpy,memmove,strcpy,strncpy 表头文件 定义函数 #include void * memccpy(void *dest, const void * src, int c,size_t n); 函数说明 返回值 memccpy()用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指 的地址上。与 memcpy()不同的是,memccpy()会在复制时检查 参数 c 是否出现,若是则返回 dest 中值为 c 的下一个字节地址。 返回指向 dest 中值为 c 的下一个字节指针。返回值为 0 表示在 src 所 指内存前 n 个字节中没有值为 c 的字节。 范例 #include main() { char a[]=”string[a]”; char b[]=”string(b)”l memccpy(a,b,’B’,sizeof(b)); printf(memccpy():%s\n”,a); } 执行 memccpy():string(b) memchr(在某一内存范围中查找一特定字符) 相关函数 表头文件 定义函数 函数说明 返回值 index,rindex,strchr,strpbrk,strrchr,strsep,strspn,strstr #include void * memchr(const void *s,int c,size_t n); memchr()从头开始搜寻 s 所指的内存内容前 n 个字节,直到发现 第一个值为 c 的字节,则返回指向该字节的指针。 如果找到指定的字节则返回该字节的指针,否则返回 0。 范例 #include main() { char *s=”0123456789012345678901234567890”; char *p; p=memchr(s,’5’,10); printf(“%s\n”,p); } 执行 56789012345678901234567890 memcmp(比较内存内容) 相关函数 表头文件 定义函数 函数说明 bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp #include int memcmp (const void *s1,const void *s2,size_t n); memcmp()用来比较 s1 和 s2 所指的内存区间前 n 个字符。字符串 大小的比较是以 ASCII 码表上的顺序来决定,次顺序亦为字符的值。 memcmp()首先将 s1 第一个字符值减去 s2 第一个字符的值,若 差为 0 则再继续比较下个字符,若差值不为 0 则将差值返回。例如, 返回值 字符串“Ac”和“ba”比较则会返回字符‘A’(65)和‘b’(98)的 差值(-33)。 若参数 s1 和 s2 所指的内存内容都完全相同则返回 0 值。s1 若大于 s2 则返回大于 0 的值。s1 若小于 s2 则返回小于 0 的值。 范例 #include main() { char *a =”aBcDeF”; char *b=”AbCdEf”; char *c=”aacdef”; char *d=”aBcDeF”; printf(“memcmp(a,b):%d\n”,memcmp((void*)a,(void*) b,6)); printf(“memcmp(a,c):%d\n”,memcmp((void*)a,(void*) c,6)); printf(“memcmp(a,d):%d\n”,memcmp((void*)a,(void*) d,6)); 执行 memcmp(a,b):1 /*字符串 a>字符串 b,返回 1*/ memcmp(a,c):-1 /* 字符串 a<字符串 c,返回-1*/ memcmp(a,d):0 /*字符串 a=字符串 d,返回 0*/ memcpy(拷贝内存内容) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 bcopy,memccpy,memcpy,memmove,strcpy,strncpy #include void * memcpy (void * dest ,const void *src, size_t n); memcpy()用来拷贝 src 所指的内存内容前 n 个字节到 dest 所指的 内存地址上。与 strcpy()不同的是,memcpy()会完整的复制 n 个字节,不会因为遇到字符串结束‘\0‘而结束。 返回指向 dest 的指针。 指针 src 和 dest 所指的内存区域不可重叠。 范例 #include main() { char a[30]=”string (a)”; char b[30]=”string\0string”; int i; strcpy(a,b); printf(strcpy():”); for(i=0;i<30;i++) printf(“%c”,a[i]); memcpy(a,b,30); printf(“\nmemcpy() :”); for(i=0;i<30;i++) printf(“%c”,a[i]); } 执行 strcpy() : string a ) memcpy() : string string memmove(拷贝内存内容) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 bcopy,memccpy,memcpy,strcpy,strncpy #include void * memmove(void *dest,const void *src,size_t n); memmove()与 memcpy()一样都是用来拷贝 src 所指的内存内 容前 n 个字节到 dest 所指的地址上。不同的是,当 src 和 dest 所指的 内存区域重叠时,memmove()仍然可以正确的处理,不过执行 效率上会比使用 memcpy()略慢些。 返回指向 dest 的指针。 指针 src 和 dest 所指的内存区域可以重叠。 范例 参考 memcpy()。 memset(将一段内存空间填入某值) 相关函数 bzero,swab 表头文件 #include 定义函数 void * memset (void *s ,int c, size_t n); 函数说明 返回值 memset()会将参数 s 所指的内存区域前 n 个字节以参数 c 填入, 然后返回指向 s 的指针。在编写程序时,若需要将某一数组作初始 化,memset()会相当方便。 返回指向 s 的指针。 附加说明 参数 c 虽声明为 int, 但必须是 unsigned char ,所以范围在 0 到 255 之间。 范例 #include main() { char s[30]; memset (s,’A’,sizeof(s)); s[30]=’\0’; printf(“%s\n”,s); } 执行 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA rindex(查找字符串中最后一个出现的指定字符) 相关函数 表头文件 定义函数 函数说明 返回值 index,memchr,strchr,strrchr #include char * rindex( const char *s,int c); rindex()用来找出参数 s 字符串中最后一个出现的参数 c 地址, 然后将该字符出现的地址返回。字符串结束字符( NULL)也视为 字符串一部分。 如果找到指定的字符则返回该字符所在的地址,否则返回 0。 范例 #include mian() { char *s =”0123456789012345678901234567890”; char *p; p= rindex(s,’5’); printf(“%s\n”,p); } 执行 567890 strcasecmp(忽略大小写比较字符串) 相关函数 表头文件 定义函数 函数说明 返回值 范例 bcmp,memcmp,strcmp,strcoll,strncmp #include int strcasecmp ( const char *s1, const char *s2); strcasecmp()用来比较参数 s1 和 s2 字符串,比较时会自动忽略大 小写的差异。 若参数 s1 和 s2 字符串相同则返回 0。s1 长度大于 s2 长度则返回大 于 0 的值,s1 长度若小于 s2 长度则返回小于 0 的值。 #include main() { char *a=”aBcDeF”; char *b= “AbCdEf”; if(!strcasecmp(a,b)) printf(“%s=%s\n”,a,b); } 执行 aBcDeF=AbCdEf strcat(连接两字符串) 相关函数 表头文件 定义函数 函数说明 返回值 bcopy,memccpy,memcpy,strcpy,strncpy #include char *strcat (char *dest,const char *src); strcat()会将参数 src 字符串拷贝到参数 dest 所指的字符串尾。第 一个参数 dest 要有足够的空间来容纳要拷贝的字符串。 返回参数 dest 的字符串起始地址 范例 #include main() { char a[30]=”string(1)”; char b[]=”string(2)”; printf(“before strcat() : %s\n”,a); printf(“after strcat() : %s\n”,strcat(a,b)); } 执行 before strcat () : string(1) after strcat () : string(1)string(2) strchr(查找字符串中第一个出现的指定字符) 相关函数 表头文件 定义函数 函数说明 返回值 index,memchr,rinex,strbrk,strsep,strspn,strstr,strtok #include char * strchr (const char *s,int c); strchr()用来找出参数 s 字符串中第一个出现的参数 c 地址,然后 将该字符出现的地址返回。 如果找到指定的字符则返回该字符所在地址,否则返回 0。 范例 #include main() { char *s=0123456789012345678901234567890”; char *p; p=strchr(s,’5’); printf(“%s\n”,p); } 执行 56789012345678901234567890 strcmp(比较字符串) 相关函数 表头文件 定义函数 函数说明 返回值 bcmp,memcmp,strcasecmp,strncasecmp,strcoll #include int strcmp(const char *s1,const char *s2); strcmp()用来比较参数 s1 和 s2 字符串。字符串大小的比较是以 ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp()首先 将 s1 第一个字符值减去 s2 第一个字符值,若差值为 0 则再继续比 较下个字符,若差值不为 0 则将差值返回。例如字符串“Ac”和 “ba”比较则会返回字符“A”(65)和‘b’(98)的差值(-33)。 若参数 s1 和 s2 字符串相同则返回 0。s1 若大于 s2 则返回大于 0 的值。 s1 若小于 s2 则返回小于 0 的值。 范例 #include main() { char *a=”aBcDeF”; char *b=”AbCdEf”; char *c=”aacdef”; char *d=”aBcDeF”; printf(“strcmp(a,b) : %d\n”,strcmp(a,b)); printf(“strcmp(a,c) : %d\n”,strcmp(a,c)); printf(“strcmp(a,d) : %d\n”,strcmp(a,d)); } 执行 strcmp(a,b) : 32 strcmp(a,c) :-31 strcmp(a,d) : 0 strcoll(采用目前区域的字符排列次序来比较字符串) 相关函数 strcmp,bcmp,memcmp,strcasecmp,strncasecmp 表头文件 #include 定义函数 int strcoll( const char *s1, const char *s2); 函数说明 返回值 附加说明 strcoll()会依环境变量 LC_COLLATE 所指定的文字排列次序来 比较 s1 和 s2 字符串。 若参数 s1 和 s2 字符串相同则返回 0。s1 若大于 s2 则返回大于 0 的值。 s1 若小于 s2 则返回小于 0 的值。 若 LC_COLLATE 为“POSIX”或“C”,则 strcoll()与 strcmp() 作用完全相同。 范例 参考 strcmp()。 strcpy(拷贝字符串) 相关函数 bcopy,memcpy,memccpy,memmove 表头文件 #include 定义函数 char *strcpy(char *dest,const char *src); 函数说明 strcpy()会将参数 src 字符串拷贝至参数 dest 所指的地址。 返回值 返回参数 dest 的字符串起始地址。 附加说明 如 果 参 数 dest 所 指 的 内 存 空 间 不 够 大 , 可 能 会 造 成 缓 冲 溢 出 (buffer Overflow)的错误情况,在编写程序时请特别留意,或者 用 strncpy()来取代。 范例 #include main() { char a[30]=”string(1)”; char b[]=”string(2)”; printf(“before strcpy() :%s\n”,a); printf(“after strcpy() :%s\n”,strcpy(a,b)); } 执行 before strcpy() :string(1) after strcpy() :string(2) strcspn(返回字符串中连续不含指定字符串内容的字符数) 相关函数 表头文件 strspn #inclued 定义函数 函数说明 返回值 size_t strcspn ( const char *s,const char * reject); strcspn()从参数 s 字符串的开头计算连续的字符,而这些字符都 完全不在参数 reject 所指的字符串中。简单地说,若 strcspn()返 回的数值为 n,则代表字符串 s 开头连续有 n 个字符都不含字符串 reject 内的字符。 返回字符串 s 开头连续不含字符串 reject 内的字符数目。 范例 #include main() { char *str=”Linux was first developed for 386/486-based pcs.”; printf(“%d\n”,strcspn(str,” “)); printf(“%d\n”,strcspn(str,”/-“)); printf(“%d\n”,strcspn(str,”1234567890”)); } 执行 5 /*只计算到“ ”的出现,所以返回“Linux”的长度*/ 33 /*计算到出现“/”或“-”,所以返回到“6”的长度*/ 30 /* 计算到出现数字字符为止,所以返回“3”出现前的长度*/ strdup(复制字符串) 相关函数 表头文件 定义函数 函数说明 返回值 calloc,malloc,realloc,free #include char * strdup( const char *s); strdup()会先用 maolloc()配置与参数 s 字符串相同的空间大小, 然后将参数 s 字符串的内容复制到该内存地址,然后把该地址返回。 该地址最后可以利用 free()来释放。 返回一字符串指针,该指针指向复制后的新字符串地址。若返回 NULL 表示内存不足。 范例 #include main() { char a[]=”strdup”; char *b; b=strdup(a); printf(“b[ ]=\”%s\”\n”,b); } 执行 b[ ]=”strdup” strlen(返回字符串长度) 相关函数 表头文件 定义函数 函数说明 返回值 无 #include size_t strlen ( const char *s); strlen()用来计算指定的字符串 s 的长度,不包括结束字符“\0”。 返回字符串 s 的字符数。 范例 /*取得字符串 str 的长度*/ #include main() { char *str =”12345678”; printf(“str length = %d\n”,strlen(str)); } 执行 str length = 8 strncasecmp(忽略大小写比较字符串) 相关函数 bcmp,memcmp,strcmp,strcoll,strncmp 表头文件 定义函数 #include int strncasecmp(const char *s1,const char *s2,size_t n); 函数说明 返回值 strncasecmp()用来比较参数 s1 和 s2 字符串前 n 个字符,比较时 会自动忽略大小写的差异。 若参数 s1 和 s2 字符串相同则返回 0。s1 若大于 s2 则返回大于 0 的值, s1 若小于 s2 则返回小于 0 的值。 范例 #include main() { char *a=”aBcDeF”; char *b=”AbCdEf”; if(!strncasecmp(a,b)) printf(“%s =%s\n”,a,b); } 执行 aBcDef=AbCdEf strncat(连接两字符串) 相关函数 表头文件 定义函数 函数说明 返回值 bcopy,memccpy,memecpy,strcpy,strncpy #inclue char * strncat(char *dest,const char *src,size_t n); strncat()会将参数 src 字符串拷贝 n 个字符到参数 dest 所指的字 符串尾。第一个参数 dest 要有足够的空间来容纳要拷贝的字符串。 返回参数 dest 的字符串起始地址。 范例 #include main() { char a[30]=”string(1)”; char b[]=”string(2)”; printf(“before strnact() :%s\n”,a); printf(“after strncat() :%s\n”,strncat(a,b,6)); } 执行 before strnact() : string(1) after strncat() : string(1) string strncpy(拷贝字符串) 相关函数 表头文件 定义函数 函数说明 返回值 bcopy,memccpy,memcpy,memmove #include char * strncpy(char *dest,const char *src,size_t n); strncpy()会将参数 src 字符串拷贝前 n 个字符至参数 dest 所指的 地址。 返回参数 dest 的字符串起始地址。 范例 #inclue main() { char a[30]=”string(1)”; char b[]=”string(2)”; printf(“before strncpy() : %s\n”,a); printf(after strncpy() : %s\n”,strncpy(a,b,6)); } 执行 before strncpy() : string(1) after strncpy() : string(1) strpbrk(查找字符串中第一个出现的指定字符) 相关函数 表头文件 定义函数 函数说明 返回值 index,memchr,rindex,strpbrk,strsep,strspn,strstr,strtok #include char *strpbrk(const char *s,const char *accept); strpbrk()用来找出参数 s 字符串中最先出现存在参数 accept 字符 串中的任意字符。 如果找到指定的字符则返回该字符所在地址,否则返回 0。 范例 #include main() { char *s=”0123456789012345678901234567890”; char *p; p=strpbrk(s,”a1 839”); /*1 会最先在 s 字符串中找到*/ printf(“%s\n”,p); p=strprk(s,”4398”);/*3 会最先在 s 字符串中找到*/ printf(“%s\n”,p); 执行 123456789012345678901234567890 3456789012345678901234567890 strrchr(查找字符串中最后出现的指定字符) 相关函数 index,memchr,rindex,strpbrk,strsep,strspn,strstr,strtok 表头文件 定义函数 函数说明 返回值 #include char * strrchr(const char *s, int c); strrchr()用来找出参数 s 字符串中最后一个出现的参数 c 地址, 然后将该字符出现的地址返回。 如果找到指定的字符则返回该字符所在地址,否则返回 0。 范例 #include main() { char *s=”0123456789012345678901234567890”; char *p; p=strrchr(s,’5’); printf(“%s\n”,p); } 执行 567890 strspn(返回字符串中连续不含指定字符串内容的字符数) 相关函数 表头文件 定义函数 函数说明 返回值 strcspn,strchr,strpbrk,strsep,strstr #include size_t strspn (const char *s,const char * accept); strspn()从参数 s 字符串的开头计算连续的字符,而这些字符都 完全是 accept 所指字符串中的字符。简单的说,若 strspn()返回的 数值为 n,则代表字符串 s 开头连续有 n 个字符都是属于字符串 accept 内的字符。 返回字符串 s 开头连续包含字符串 accept 内的字符数目。 范例 #include main() { char *str=”Linux was first developed for 386/486-based PCs.”; char *t1=”abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”; printf(“%d\n”,strspn(str,t1)); } 执行 5 /*计算大小写字母。不包含“ ”,所以返回 Linux 的长度。*/ strstr(在一字符串中查找指定的字符串) 相关函数 表头文件 定义函数 函数说明 返回值 index,memchr,rindex,strchr,strpbrk,strsep,strspn,strtok #include char *strstr(const char *haystack,const char *needle); strstr()会从字符串 haystack 中搜寻字符串 needle,并将第一次出 现的地址返回。 返回指定字符串第一次出现的地址,否则返回 0。 范例 #include main() { char * s=”012345678901234567890123456789”; char *p; p= strstr(s,”901”); printf(“%s\n”,p); } 执行 9012345678901234567890 strtok(分割字符串) 相关函数 表头文件 定义函数 函数说明 返回值 index,memchr,rindex,strpbrk,strsep,strspn,strstr #include char * strtok(char *s,const char *delim); strtok()用来将字符串分割成一个个片段。参数 s 指向欲分割的字 符串,参数 delim 则为分割字符串,当 strtok()在参数 s 的字符串 中发现到参数 delim 的分割字符时则会将该字符改为\0 字符。在第 一次调用时,strtok()必需给予参数 s 字符串,往后的调用则将参 数 s 设置成 NULL。每次调用成功则返回下一个分割后的字符串指 针。 返回下一个分割后的字符串指针,如果已无从分割则返回 NULL。 范例 #include main() { char s[]=”ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z”; char *delim=”-: “; char *p; printf(%s “;strtok(s,delim)); while((p=strtok(NULL,delim)))printf(“%s ”,p); printf(“\n”); } 执行 ab cd ef;gh i jkl;mnop;qrs tu vwx y;z /*-与:字符已经被\0 字符取代*/ abs(计算整型数的绝对值) 相关函数 表头文件 定义函数 函数说明 返回值 labs, fabs #include int abs (int j) abs () 用来计算参数 j 的绝对值,然后将结果返回。 返回参数 j 的绝对值结果。 范例 #ingclude main(){ int ansert; answer = abs(-12); printf(“|-12| = %d\n” , answer); } 执行 |-12| = 12 acos(取反余弦函数数值) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 附加说明 asin , atan , atan2 , cos , sin , tan #include double acos (double x); acos () 用来计算参数 x 的反余弦值,然后将结果返回。参数 x 范围 为-1 至 1 之间,超过此范围则会失败。 返回 0 至 PI 之间的计算结果,单位为弧度,在函数库中角度均以 弧度来表示。 EDOM 参数 x 超出范围。 使用 GCC 编译时请加入-lm。 范例 #include main (){ double angle; angle = acos(0.5); printf (“angle = %f\n” , angle); } 执行 angle = 1.047198 asin(取反正弦函数值) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 附加说明 acos , atan , atan2 , cos , sin , tan #include double asin (double x) asin () 用来计算参数 x 的反正弦值,然后将结果返回。参数 x 范围 为-1 至 1 之间,超过此范围则会失败。 返回-PI/2 之 PI/2 之间的计算结果。 EDOM 参数 x 超出范围 使用 GCC 编译时请加入 -lm 范例 #include main() { double angle; angle = asin (0.5); printf(“angle = %f\n”,angle); } 执行 angle = 0.523599 atan(取反正切函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 acos,asin,atan2,cos,sin,tan #include double atan(double x); atan()用来计算参数 x 的反正切值,然后将结果返回。 返回-PI/2 至 PI/2 之间的计算结果。 使用 GCC 编译时请加入-lm 范例 #include main() { double angle; angle =atan(1); printf(“angle = %f\n”,angle); } 执行 angle = 1.570796 atan2(取得反正切函数值) 相关函数 表头文件 acos,asin,atan,cos,sin,tan #include 定义函数 函数说明 返回值 附加说明 double atan2(double y,double x); atan2()用来计算参数 y/x 的反正切值,然后将结果返回。 返回-PI/2 至 PI/2 之间的计算结果。 使用 GCC 编译时请加入-lm。 范例 #include main() { double angle; angle = atan2(1,2); printf(“ angle = %f\n”,angle); } 执行 angle = 0.463648 ceil(取不小于参数的最小整型数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 fabs #include double ceil (double x); ceil()会返回不小于参数 x 的最小整数值,结果以 double 形态返 回。 返回不小于参数 x 的最小整数值。 使用 GCC 编译时请加入-lm。 范例 #include main() { double value[ ]={4.8,1.12,-2.2,0}; int i; for (i=0;value[i]!=0;i++) printf(“%f=>%f\n”,value[i],ceil(value[i])); } 执行 4.800000=>5.000000 1.120000=>2.000000 -2.200000=>-2.000000 cos(取余玄函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 acos,asin,atan,atan2,sin,tan #include double cos(double x); cos()用来计算参数 x 的余玄值,然后将结果返回。 返回-1 至 1 之间的计算结果。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer = cos(0.5); printf(“cos (0.5) = %f\n”,answer); } 执行 cos(0.5) = 0.877583 cosh(取双曲线余玄函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 sinh,tanh #include double cosh(double x); cosh()用来计算参数 x 的双曲线余玄值,然后将结果返回。数学 定义式为:(exp(x)+exp(-x))/2。 返回参数 x 的双曲线余玄值。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer = cosh(0.5); printf(“cosh(0.5) = %f\n”,answer); } 执行 cosh(0.5) = 1.127626 exp(计算指数) 相关函数 log,log10,pow 表头文件 定义函数 函数说明 返回值 附加说明 #include double exp(double x); exp()用来计算以 e 为底的 x 次方值,即 ex 值,然后将结果返回。 返回 e 的 x 次方计算结果。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer; answer = exp (10); printf(“ e^10 =%f\n”,answer); } 执行 e^10 = 22026.465795 frexp(将浮点型数分为底数与指数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 ldexp,modf #include double frexp( double x, int *exp); frexp()用来将参数 x 的浮点型数切割成底数和指数。底数部分直 接返回,指数部分则借参数 exp 指针返回,将返回值乘以 2 的 exp 次方即为 x 的值。 返回参数 x 的底数部分,指数部分则存于 exp 指针所指的地址。 使用 GCC 编译时请加入-lm。 范例 #include main() { int exp; double fraction; fraction = frexp (1024,&exp); printf(“exp = %d\n”,exp); printf(“fraction = %f\n”,fraction); } 执行 exp = 11 fraction = 0.500000 /* 0.5*(2^11)=1024*/ ldexp(计算 2 的次方值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 frexp #include double ldexp(double x,int exp); ldexp()用来将参数 x 乘上 2 的 exp 次方值,即 x*2exp。 返回计算结果。 使用 GCC 编译时请加入-lm。 范例 /* 计算 3*(2^2)=12 */ #include main() { int exp; double x,answer; answer = ldexp(3,2); printf(“3*2^(2) = %f\n”,answer); } 执行 3*2^(2) = 12.000000 log(计算以 e 为底的对数值) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 附加说明 exp,log10,pow #include double log (double x); log()用来计算以 e 为底的 x 对数值,然后将结果返回。 返回参数 x 的自然对数值。 EDOM 参数 x 为负数 ERANGE 参数 x 为零值,零的对数值无定义。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer; answer = log (100); printf(“log(100) = %f\n”,answer); } 执行 log(100) = 4.605170 log10(计算以 10 为底的对数值) 相关函数 exp,log,pow 表头文件 定义函数 函数说明 返回值 错误代码 附加说明 #include double log10(double x); log10()用来计算以 10 为底的 x 对数值,然后将结果返回。 返回参数 x 以 10 为底的对数值。 EDOM 参数 x 为负数。 RANGE 参数 x 为零值,零的对数值无定义。 使用 GCC 编译时请加入-lm。 范例 #include double pow(double x,double y); pow()用来计算以 x 为底的 y 次方值,即 xy 值,然后将结果返回。 返回 x 的 y 次方计算结果。 EDOM 参数 x 为负数且参数 y 不是整数。 附加说明 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer; answer =pow(2,10); printf(“2^10 = %f\n”,answer); } 执行 2^10 = 1024.000000 sin(取正玄函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 acos,asin,atan,atan2,cos,tan #include double sin(double x); sin()用来计算参数 x 的正玄值,然后将结果返回。 返回-1 至 1 之间的计算结果。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer = sin (0.5); printf(“sin(0.5) = %f\n”,answer); } 执行 sin(0.5) = 0.479426 sinh(取双曲线正玄函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 cosh,tanh #include double sinh( double x); sinh()用来计算参数 x 的双曲线正玄值,然后将结果返回。数学定 义式为:(exp(x)-exp(-x))/2。 返回参数 x 的双曲线正玄值。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer = sinh (0.5); printf(“sinh(0.5) = %f\n”,answer); } 执行 sinh(0.5) = 0.521095 sqrt(计算平方根值) 相关函数 表头文件 hypotq #include 定义函数 函数说明 返回值 错误代码 附加说明 double sqrt(double x); sqrt()用来计算参数 x 的平方根,然后将结果返回。参数 x 必须为 正数。 返回参数 x 的平方根值。 EDOM 参数 x 为负数。 使用 GCC 编译时请加入-lm。 范例 /* 计算 200 的平方根值*/ #include main() { double root; root = sqrt (200); printf(“answer is %f\n”,root); } 执行 answer is 14.142136 tan(取正切函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 atan,atan2,cos,sin #include double tan(double x); tan()用来计算参数 x 的正切值,然后将结果返回。 返回参数 x 的正切值。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer = tan(0.5); printf(“tan (0.5) = %f\n”,answer); } 执行 tan(0.5) = 0.546302 tanh(取双曲线正切函数值) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 cosh,sinh #include double tanh(double x); tanh()用来计算参数 x 的双曲线正切值,然后将结果返回。数学 定义式为:sinh(x)/cosh(x)。 返回参数 x 的双曲线正切值。 使用 GCC 编译时请加入-lm。 范例 #include main() { double answer = tanh(0.5); printf(“ tanh(0.5) = %f\n”,answer); } 执行 tanh(0.5) = 0.462117 endgrent(关闭组文件) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 getgrent,setgrent #include #include void endgrent(void); endgrent()用来关闭由 getgrent()所打开的密码文件。 无 无 范例 请参考 getgrent()与 setgrent()。 endpwent(关闭密码文件) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 getpwent,setpwent #include #include void endpwent(void); endpwent()用来关闭由 getpwent()所打开的密码文件。 无 无 范例 请参考 getpwent()与 setpwent()。 endutent(关闭 utmp 文件) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 getutent,setutent #include void endutent(void); endutent()用来关闭由 getutent 所打开的 utmp 文件。 无 无 范例 请参考 getutent()。 fgetgrent(从指定的文件来读取组格式) 相关函数 表头文件 定义函数 函数说明 返回值 fgetpwent #include #include #include struct group * getgrent(FILE * stream); fgetgrent()会从参数 stream 指定的文件读取一行数据,然后以 group 结 构 将 该 数 据 返 回 。 参 数 stream 所 指 定 的 文 件 必 须 和 、 etc/group 相同的格式。group 结构定义请参考 getgrent()。 返回 group 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 范例 #include #include #include main() { struct group *data; FILE *stream; int i; stream = fopen(“/etc/group”,”r”); while((data = fgetgrent(stream))!=0){ i=0; printf(“ %s :%s:%d :”,data->gr_name,data->gr_passwd,data->gr_gid); while (data->gr_mem[i])printf(“%s,”,data->gr_mem[i++]); printf(“\n”); } fclose(stream); } 执行 root:x:0:root, bin:x:1:root,bin,daemon daemon:x:2:root,bin,daemon sys:x:3:root,bin,adm adm:x:4:root,adm,daemon tty:x:5 disk:x:6:root lp:x:7:daemon,lp mem:x:8 kmem:x:9 wheel:x:10:root mail:x:12:mail news:x:13:news uucp:x:14:uucp man:x:15 games:x:20 gopher:x:30 dip:x:40: ftp:x:50 nobody:x:99: fgetpwent(从指定的文件来读取密码格式) 相关函数 fgetgrent 表头文件 定义函数 #include #include #include struct passwd * fgetpwent(FILE *stream); 函数说明 返回值 fgetpwent()会从参数 stream 指定的文件读取一行数据,然后以 passwd 结 构 将 该 数 据 返 回 。 参 数 stream 所 指 定 的 文 件 必 须 和 /etc/passwd 相同的格式。passwd 结构定义请参考 getpwent()。 返回 passwd 结构数据,如果返回 NULL 则表示已无数据,或有错 误发生。 范例 #include #include main() { struct passwd *user; FILE *stream; stream = fopen(“/etc/passwd”,”r”); while((user = fgetpwent(stream))!=0){ printf(“%s:%d:%d:%s:%s:%s\n”,user->pw_name,user->pw_uid,user->pw_gid, user->pw_gecos,user->pw_dir,user->pw_shell); } } 执行 root:0:0:root:/root:/bin/bash bin:1:1:bin:/bin: daemon:2:2:daemon:/sbin: adm:3:4:adm:/var/adm: lp:4:7:lp:/var/spool/lpd: sync:5:0:sync:/sbin:/bin/sync shutdown:6:0:shutdown:/sbin:/sbin/shutdown halt:7:0:halt:/sbin:/sbin/halt mail:8:12:mail:/var/spool/mail: news:9:13:news:var/spool/news uucp:10:14:uucp:/var/spool/uucp: operator:11:0:operator :/root: games:12:100:games:/usr/games: gopher:13:30:gopher:/usr/lib/gopher-data: ftp:14:50:FTP User:/home/ftp: nobody:99:99:Nobody:/: xfs:100:101:X Font Server: /etc/Xll/fs:/bin/false gdm:42:42:/home/gdm:/bin/bash kids:500:500: : /home/kids:/bin/bash getegid(取得有效的组识别码) 相关函数 表头文件 定义函数 函数说明 返回值 getgid,setgid,setregid #include #include gid_t getegid(void); getegid()用来取得执行目前进程有效组识别码。有效的组识别码 用来决定进程执行时组的权限。 返回有效的组识别码。 范例 main() { printf(“egid is %d\n”,getegid()); } 执行 egid is 0 /*当使用 root 身份执行范例程序时*/ geteuid(取得有效的用户识别码) 相关函数 表头文件 定义函数 函数说明 返回值 getuid,setreuid,setuid #include #include uid_t geteuid(void) geteuid()用来取得执行目前进程有效的用户识别码。有效的用户 识别码用来决定进程执行的权限,借由此改变此值,进程可以获得 额外的权限。倘若执行文件的 setID 位已被设置,该文件执行时,其 进 程 的 euid 值 便 会 设 成 该 文 件 所 有 者 的 uid 。 例 如 , 执 行 文 件 /usr/bin/passwd 的权限为-r-s--x--x,其 s 位即为 setID(SUID)位, 而 当 任 何 用 户 在 执 行 passwd 时 其 有 效 的 用 户 识 别 码 会 被 设 成 passwd 所有者的 uid 值,即 root 的 uid 值(0)。 返回有效的用户识别码。 范例 main() { printf (“euid is %d \n”,geteuid()); } 执行 euid is 0 /*当使用 root 身份执行范例程序时*/ getgid(取得真实的组识别码) 相关函数 表头文件 定义函数 getegid,setregid,setgid #include #include gid_t getgid(void); 函数说明 返回值 getgid()用来取得执行目前进程的组识别码。 返回组识别码 范例 main() { printf(“gid is %d\n”,getgid()); } 执行 gid is 0 /*当使用 root 身份执行范例程序时*/ getgrent(从组文件中取得账号的数据) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 错误代码 setgrent,endgrent #include #include struct group *getgrent(void); getgrent()用来从组文件(/etc/group)中读取一项组数据,该数据以 group 结构返回。第一次调用时会取得第一项组数据,之后每调用一 次就会返回下一项数据,直到已无任何数据时返回 NULL。 struct group{ char *gr_name; /*组名称*/ char *gr_passwd; /* 组密码*/ gid_t gr_gid; /*组识别码*/ char **gr_mem; /*组成员账号*/ } 返回 group 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 getgrent()在第一次调用时会打开组文件,读取数据完毕后可使 用 endgrent()来关闭该组文件。 ENOMEM 内存不足,无法配置 group 结构。 范例 #include #include main() { struct group *data; int i; while((data= getgrent())!=0){ i=0; printf(“%s:%s:%d:”,data->gr_name,data->gr_passwd,data->gr_gid); while(data->gr_mem[i])printf(“%s,”,data->gr_mem[i++]); printf(“\n”); } endgrent(); } 执行 root:x:0:root, bin:x:1:root,bin,daemon, daemon:x:2:root,bin,daemon, sys:x:3:root,bin,adm, adm:x:4:root,adm,daemon tty:x:5 disk:x:6:root lp:x:7:daemon,lp mem:x:8 kmem:x:9: wheel:x:10:root mail:x:12:mail news:x:13:news uucp:x:14:uucp man:x:15: games:x:20 gopher:x:30 dip:x:40 ftp:x:50 nobody:x:99 getgrgid(从组文件中取得指定 gid 的数据) 相关函数 fgetgrent,getgrent,getgrnam 表头文件 定义函数 #include #include strcut group * getgrgid(gid_t gid); 函数说明 返回值 getgrgid()用来依参数 gid 指定的组识别码逐一搜索组文件,找到 时 便 将 该 组 的 数 据 以 group 结 构 返 回 。 group 结 构 请 参 考 getgrent()。 返回 group 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 范例 /* 取得 gid=3 的组数据*/ #include #include main() { strcut group *data; int i=0; data = getgrgid(3); printf(“%s:%s:%d:”,data->gr_name,data->gr_passwd,data->gr_gid); while(data->gr_mem[i])printf(“%s ,”,data->mem[i++]); printf(“\n”); } 执行 sys:x:3:root,bin,adm getgrnam(从组文件中取得指定组的数据) 相关函数 表头文件 定义函数 函数说明 fgetgrent,getrent,getgruid #include #include strcut group * getgrnam(const char * name); getgrnam()用来逐一搜索参数那么指定的组名称,找到时便将该 组的数据以 group 结构返回。group 结构请参考 getgrent()。 返回值 返回 group 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 范例 /* 取得 adm 的组数据*/ #include #include main() { strcut group * data; int i=0; data = getgrnam(“adm”); printf(“%s:%s:%d:”,data->gr_name,data->gr_passwd,data->gr_gid); while(data->gr_mem[i])printf(“%s,”,data->gr_mem[i++]); printf(“\n”); } 执行 adm:x:4:root,adm,daemon getgroups(取得组代码) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 范例 initgroups,setgroup,getgid,setgid #include #include int getgroups(int size,gid_t list[]); getgroup()用来取得目前用户所属的组代码。参数 size 为 list〔〕所 能容纳的 gid_t 数目。如果参数 size 值为零,此函数仅会返回用户所 属的组数。 返回组识别码,如有错误则返回-1。 EFAULT 参数 list 数组地址不合法。 EINVAL 参数 size 值不足以容纳所有的组 #include #include main() { gid_t list[500]; int x,i; x = getgroups(0.list); getgroups(x,list); for(i=0;i #include int getpw(uid_t uid,char *buf); getpw()会从/etc/passwd 中查找符合参数 uid 所指定的用户账号数 据,找不到相关数据就返回-1。所返回的 buf 字符串格式如下: 账号:密码:用户识别码(uid):组识别码(gid):全名:根目 录:shell 返回 0 表示成功,有错误发生时返回-1。 1. getpw()会有潜在的安全性问题,请尽量使用别的函数取代。 2. 使用 shadow 的系统已把用户密码抽出/etc/passwd,因此使用 getpw()取得的密码将为“x”。 范例 #include #include main() { char buffer[80]; getpw(0,buffer); printf(“%s\n”,buffer); } 执行 root:x:0:0:root:/root:/bin/bash getpwent(从密码文件中取得账号的数据) 相关函数 表头文件 定义函数 函数说明 返回值 getpw,fgetpwent,getpwnam,getpwuid,setpwent,endpwent #include #include strcut passwd * getpwent(void); getpwent()用来从密码文件(/etc/passwd)中读取一项用户数据, 该用户的数据以 passwd 结构返回。第一次调用时会取得第一位用户 数据,之后每调用一次就会返回下一项数据,直到已无任何数据时 返回 NULL。 passwd 结构定义如下: struct passwd{ char * pw_name; /*用户账号*/ char * pw_passwd; /*用户密码*/ uid_t pw_uid; /*用户识别码*/ gid_t pw_gid; /*组识别码*/ char * pw_gecos; /*用户全名*/ char * pw_dir; /*家目录*/ char * pw_shell; /* 所使用的 shell 路径*/ }; 返回 passwd 结构数据,如果返回 NULL 则表示已无数据,或有错 误发生。 附加说明 错误代码 getpwent()在第一次调用时会打开密码文件,读取数据完毕后可 使用 endpwent()来关闭该密码文件。 ENOMEM 内存不足,无法配置 passwd 结构。 范例 #include #include main() { struct passwd *user; while((user = getpwent())!=0){ printf(“%s:%d:%d:%s:%s:%s\n”,user->pw_name,user->pw_uid,user->pw_gid, user->pw_gecos,user->pw_dir,user->pw_shell); } endpwent(); } 执行 root:0:0:root:/root:/bin/bash bin:1:1:bin:/bin: daemon:2:2:daemon:/sbin: adm:3:4:adm:/var/adm: lp:4:7:lp:/var/spool/lpd: sync:5:0:sync:/sbin:/bin/sync shutdown:6:0:shutdown:/sbin:/sbin/shutdown halt:7:0:halt:/sbin:/sbin/halt mail:8:12:mail:/var/spool/mail: news:9:13:news:var/spool/news uucp:10:14:uucp:/var/spool/uucp: operator:11:0:operator :/root: games:12:100:games:/usr/games: gopher:13:30:gopher:/usr/lib/gopher-data: ftp:14:50:FTP User:/home/ftp: nobody:99:99:Nobody:/: xfs:100:101:X Font Server: /etc/Xll/fs:/bin/false gdm:42:42:/home/gdm:/bin/bash kids:500:500: : /home/kids:/bin/bash getpwnam(从密码文件中取得指定账号的数据) 相关函数 getpw,fgetpwent,getpwent,getpwuid 表头文件 定义函数 #include #include struct passwd * getpwnam(const char * name); 函数说明 返回值 getpwnam()用来逐一搜索参数 name 指定的账号名称,找到时便 将 该 用 户 的 数 据 以 passwd 结 构 返 回 。 passwd 结 构 请 参 考 getpwent()。 返回 passwd 结构数据,如果返回 NULL 则表示已无数据,或有错 误发生。 范例 /*取得 root 账号的识别码和根目录*/ #include #include main() { struct passwd *user; user = getpwnam(“root”); printf(“name:%s\n”,user->pw_name); printf(“uid:%d\n”,user->pw_uid); printf(“home:%s\n”,user->pw_dir); } 执行 name:root uid:0 home:/root getpwuid(从密码文件中取得指定 uid 的数据) 相关函数 表头文件 定义函数 getpw,fgetpwent,getpwent,getpwnam #include #include struct passwd * getpwuid(uid_t uid); 函数说明 返回值 getpwuid()用来逐一搜索参数 uid 指定的用户识别码,找到时便 将 该 用 户 的 数 据 以 passwd 结 构 返 回 。 passwd 结 构 请 参 考 getpwent()。 返回 passwd 结构数据,如果返回 NULL 则表示已无数据,或者有 错误发生。 范例 #include #include main() { struct passwd *user; user= getpwuid(6); printf(“name:%s\n”,user->pw_name); printf(“uid:%d\n”,user->pw_uid); printf(“home:%s\n”,user->pw_dir); } 执行 name:shutdown uid:6 home:/sbin getuid(取得真实的用户识别码) 相关函数 表头文件 定义函数 函数说明 返回值 geteuid,setreuid,setuid #include #include uid_t getuid(void); getuid()用来取得执行目前进程的用户识别码。 用户识别码 范例 main() { printf(“uid is %d\n”,getuid()); } 执行 uid is 0 /*当使用 root 身份执行范例程序时*/ getutent(从 utmp 文件中取得账号登录数据) 相关函数 表头文件 定义函数 函数说明 getutent,getutid,getutline,setutent,endutent,pututline,utmpna me #include struct utmp *getutent(void); getutent()用来从 utmp 文件(/var/run/utmp)中读取一项登录数 据,该数据以 utmp 结构返回。第一次调用时会取得第一位用户数据, 之后每调用一次就会返回下一项数据,直到已无任何数据时返回 NULL。 utmp 结构定义如下: struct utmp { short int ut_type; /*登录类型*/ pid_t ut_pid; /*login 进程的 pid*/ char ut_line[UT_LINESIZE];/*登录装置名,省略了“/dev/”*/ char ut_id[4]; /* Inittab ID*/ char ut_user[UT_NAMESIZE];/*登录账号*/ char ut_host[UT_HOSTSIZE];/*登录账号的远程主机名称*/ struxt exit_status ut_exit;/* 当类型为 DEAD_PROCESS 时进程的结 束状态*/ long int ut_session; /*Sessioc ID*/ struct timeval ut_tv; /*时间记录*/ int32_t ut_addr_v6[4]; /*远程主机的网络地址*/ char __unused[20]; /* 保留未使用*/ }; ut_type 有以下几种类型: EMPTY 此为空的记录。 RUN_LVL 记录系统 run-level 的改变 BOOT_TIME 记录系统开机时间 NEW_TIME 记录系统时间改变后的时间 OLD_TINE 记录当改变系统时间时的时间。 INIT_PROCESS 记录一个由 init 衍生出来的进程。 LOGIN_PROCESS 记录 login 进程。 USER_PROCESS 记录一般进程。 DEAD_PROCESS 记录一结束的进程。 ACCOUNTING 目前尚未使用。 返回值 附加说明 exit_status 结构定义: struct exit_status { short int e_termination; /*进程结束状态*/ short int e_exit; /*进程退出状态*/ }; timeval 的结构定义请参考 gettimeofday()。 相关常数定义如下: UT_LINESIZE 32 UT_NAMESIZE 32 UT_HOSTSIZE 256 返回 utmp 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 getutent()在第一次调用时会打开 utmp 文件,读取数据完毕后可 使用 endutent()来关闭该 utmp 文件。 范例 #include main() { struct utmp *u; while((u=getutent())){ if(u->ut_type = = USER_PROCESS) printf(“%d %s %s %s \n”,u->ut_type,u->ut_user,u->ut_line,u->ut_host); } endutent(); } 执行 /* 表示有三个 root 账号分别登录/dev/pts/0,/dev/pts/1,/dev/pts/2 */ 7 root pts/0 7 root pts/1 7 root pts/2 getutid(从 utmp 文件中查找特定的记录) 相关函数 getutent,getutline 表头文件 定义函数 #include strcut utmp *getutid(strcut utmp *ut); 函数说明 返回值 getutid()用来从目前 utmp 文件的读写位置逐一往后搜索参数 ut 指 定 的 记 录 , 如 果 ut->ut_type 为 RUN_LVL,BOOT_TIME,NEW_TIME,OLD_TIME 其中之一则 查 找 与 ut->ut_type 相 符 的 记 录 ; 若 ut->ut_type 为 INIT_PROCESS , LOGIN_PROCESS , USER_PROCESS 或 DEAD_PROCESS 其中之一,则查找与 ut->ut_id 相符的记录。找到 相 符 的 记 录 便 将 该 数 据 以 utmp 结 构 返 回 。 utmp 结 构 请 参 考 getutent()。 返回 utmp 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 范例 #include main() { struct utmp ut,*u; ut.ut_type=RUN_LVL; while((u= getutid(&ut))){ printf(“%d %s %s %s\n”,u->ut_type,u->ut_user,u->ut_line,u->ut_host); } } 执行 1 runlevel - getutline(从 utmp 文件中查找特定的记录) 相关函数 getutent,getutid,pututline 表头文件 定义函数 #include struct utmp * getutline (struct utmp *ut); 函数说明 返回值 getutline ( ) 用 来 从 目 前 utmp 文 件 的 读 写 位 置 逐 一 往 后 搜 索 ut_type 为 USER_PROCESS 或 LOGIN_PROCESS 的 记 录 , 而 且 ut_line 和 ut->ut_line 相符。找到相符的记录便将该数据以 utmp 结构 返回,utmp 结构请参考 getutent()。 返回 utmp 结构数据,如果返回 NULL 则表示已无数据,或有错误 发生。 范例 #include main() { struct utmp ut,*u; strcpy (ut.ut_line,”pts/1”); while ((u=getutline(&ut))){ printf(“%d %s %s %s \n”,u->ut_type,u->ut_user,u->ut_line,u->ut_host); } } 执行 7 root pts/1 initgroups(初始化组清单) 相关函数 表头文件 定义函数 函数说明 返回值 setgrent,endgrent #include #include int initgroups(const char *user,gid_t group); initgroups()用来从组文件(/etc/group)中读取一项组数据,若该 组数据的成员中有参数 user 时,便将参数 group 组识别码加入到此 数据中。 执行成功则返回 0,失败则返回-1,错误码存于 errno。 pututline(将 utmp 记录写入文件) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 getutent,getutid,getutline #include void pututline(struct utmp *ut); pututline()用来将参数 ut 的 utmp 结构记录到 utmp 文件中。此函 数会先用 getutid()来取得正确的写入位置,如果没有找到相符的 记录则会加入到 utmp 文件尾,utmp 结构请参考 getutent()。 无 需要有写入/var/run/utmp 的权限 范例 #include main() { struct utmp ut; ut.ut_type =USER_PROCESS; ut.ut_pid=getpid(); strcpy(ut.ut_user,”kids”); strcpy(ut.ut_line,”pts/1”); strcpy(ut.ut_host,”www.gnu.org”); pututline(&ut); } 执行 /*执行范例后用指令 who -l 观察*/ root pts/0 dec9 19:20 kids pts/1 dec12 10:31(www.gnu.org) root pts/2 dec12 13:33 seteuid(设置有效的用户识别码) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 setuid,setreuid,setfsuid #include int seteuid(uid_t euid); seteuid()用来重新设置执行目前进程的有效用户识别码。在 Linux 下,seteuid(euid)相当于 setreuid(-1,euid)。 执行成功则返回 0,失败则返回-1,错误代码存于 errno 请参考 setuid setfsgid(设置文件系统的组识别码) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 错误代码 setuid,setreuid,seteuid,setfsuid #include int setfsgid(uid_t fsgid); setfsgid()用来重新设置目前进程的文件系统的组识别码。一般情 况下,文件系统的组识别码(fsgid)与有效的组识别码(egid)是 相同的。如果是超级用户调用此函数,参数 fsgid 可以为任何值,否 则参数 fsgid 必须为 real/effective/saved 的组识别码之一。 执行成功则返回 0,失败则返回-1,错误代码存于 errno。 此函数为 Linux 特有。 EPERM 权限不够,无法完成设置。 setfsuid(设置文件系统的用户识别码) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 错误代码 setuid,setreuid,seteuid,setfsgid #include int setfsuid(uid_t fsuid); setfsuid()用来重新设置目前进程的文件系统的用户识别码。一般 情况下,文件系统的用户识别码( fsuid)与有效的用户识别码 (euid)是相同的。如果是超级用户调用此函数,参数 fsuid 可以为 任何值,否则参数 fsuid 必须为 real/effective/saved 的用户识别码之 一。 执行成功则返回 0,失败则返回-1,错误代码存于 errno 此函数为 Linux 特有 EPERM 权限不够,无法完成设置。 setgid(设置真实的组识别码) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 getgid,setregid,getegid,setegid #include int setgid(gid_t gid); setgid()用来将目前进程的真实组识别码(real gid)设成参数 gid 值。如果是以超级用户身份执行此调用,则 real、effective 与 saved gid 都会设成参数 gid。 设置成功则返回 0,失败则返回-1,错误代码存于 errno 中。 EPERM 并 非 以 超 级 用 户 身 份 调 用 , 而 且 参 数 gid 并 非 进 程 的 effective gid 或 saved gid 值之一。 setgrent(从头读取组文件中的组数据) 相关函数 getgrent,endgrent 表头文件 定义函数 函数说明 返回值 附加说明 #include #include void setgrent(void); setgrent()用来将 getgrent()的读写地址指回组文件开头。 无 请参考 setpwent()。 setgroups(设置组代码) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 initgroups,getgroup,getgid,setgid #include int setgroups(size_t size,const gid_t * list); setgroups()用来将 list 数组中所标明的组加入到目前进程的组设 置中。参数 size 为 list〔〕的 gid_t 数目,最大值为 NGROUP(32)。 设置成功则返回 0,如有错误则返回-1。 EFAULT 参数 list 数组地址不合法。 EPERM 权限不足,必须是 root 权限 EINVAL 参数 size 值大于 NGROUP(32)。 setpwent(从头读取密码文件中的账号数据) 相关函数 表头文件 定义函数 函数说明 getpwent,endpwent #include #include void setpwent(void); setpwent()用来将 getpwent()的读写地址指回密码文件开头。 返回值 无 范例 #include #include main() { struct passwd *user; int i; for(i=0;i<4;i++){ user=getpwent(); printf(“%s :%d :%d :%s:%s:%s\n”,user->pw_name,user->pw_uid,user->pw_gid, user->pw_gecos,user->pw_dir,user->pw_shell); } setpwent(); user=getpwent(); printf(“%s :%d :%d :%s:%s:%s\n”,user->pw_name,user->pw_uid,user->pw_gid, user->pw_gecos,user->pw_dir,user->pw_shell); endpwent(); } 执行 root:0:0:root:/root:/bin/bash bin:1:1:bin:/bin daemon:2:2:daemon:/sbin adm:3:4:adm:/var/adm root:0:0:root:/root:/bin/bash setregid(设置真实及有效的组识别码) 相关函数 表头文件 定义函数 函数说明 setgid,setegid,setfsgid #include int setregid(gid_t rgid,gid_t egid); setregid()用来将参数 rgid 设为目前进程的真实组识别码,将参 数 egid 设置为目前进程的有效组识别码。如果参数 rgid 或 egid 值为1,则对应的识别码不会改变。 返回值 执行成功则返回 0,失败则返回-1,错误代码存于 errno。 setreuid(设置真实及有效的用户识别码) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 setuid,seteuid,setfsuid #include int setreuid(uid_t ruid,uid_t euid); setreuid()用来将参数 ruid 设为目前进程的真实用户识别码,将 参数 euid 设置为目前进程的有效用户识别码。如果参数 ruid 或 euid 值为-1,则对应的识别码不会改变。 执行成功则返回 0,失败则返回-1,错误代码存于 errno。 请参考 setuid()。 setuid(设置真实的用户识别码) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 getuid,setreuid,seteuid,setfsuid #include int setuid(uid_t uid) setuid()用来重新设置执行目前进程的用户识别码。不过,要让此 函数有作用,其有效的用户识别码必须为 0(root)。在 Linux 下, 当 root 使用 setuid()来变换成其他用户识别码时,root 权限会被 抛弃,完全转换成该用户身份,也就是说,该进程往后将不再具有 可 setuid()的权利,如果只是向暂时抛弃 root 权限,稍后想重新 取回权限,则必须使用 seteuid()。 执行成功则返回 0,失败则返回-1,错误代码存于 errno。 一般在编写具 setuid root 的程序时,为减少此类程序带来的系统安 全风险,在使用完 root 权限后建议马上执行 setuid(getuid());来抛 弃 root 权限。此外,进程 uid 和 euid 不一致时 Linux 系统将不会产生 core dump。 setutent(从头读取 utmp 文件中的登录数据) 相关函数 表头文件 定义函数 函数说明 附加说明 getutent,endutent #include void setutent(void); setutent()用来将 getutent()的读写地址指回 utmp 文件开头。 请参考 setpwent()或 setgrent()。 utmpname(设置 utmp 文件路径) 相关函数 表头文件 定义函数 函数说明 返回值 getutent,getutid,getutline,setutent,endutent,pututline #include void utmpname(const char * file); utmpname()用来设置 utmp 文件的路径,以提供 utmp 相关函数 的存取路径。如果没有使用 utmpname()则默认 utmp 文件路径为 /var/run/utmp。 无 crypt(将密码或数据编码) 相关函数 getpass 表头文件 定义函数 函数说明 返回值 附加说明 #define _XOPEN_SOURCE #include char * crypt (const char *key,const char * salt); crypt()将使用 Data Encryption Standard (DES)演算法将参数 key 所指的字符串加以编码,key 字符串长度仅取前 8 个字符,超过此 长度的字符没有意义。参数 salt 为两个字符组成的字符串,由 az 、A-Z、0-9,“.”和“/”所组成,用来决定使用 4096 种不同内建表 格的哪一个。函数执行成功后会返回指向编码过的字符串指针,参 数 key 所指的字符串不会有所更动。编码过的字符串长度为 13 个字 符,前两个字符为参数 salt 代表的字符串。 返回一个指向以 NULL 结尾的密码字符串。 使用 GCC 编译时需加-lcrypt。 范例 #include main() { char passwd[13]; char *key; char slat[2]; key= getpass(“Input First Password:”); slat[0]=key[0]; slat[1]=key[1]; strcpy(passwd,crypt(key slat)); key=getpass(“Input Second Password:”); slat[0]=passwd[0]; slat[1]=passwd[1]; printf(“After crypt(),1st passwd :%s\n”,passwd); printf(“After crypt(),2nd passwd:%s \n”,crypt(key slat)); } 执行 Input First Password: /* 输入 test,编码后存于 passwd[ ] */ Input Second Password /*输入 test,密码相同编码后也会相同*/ After crypt () 1st Passwd : teH0wLIpW0gyQ After crypt () 2nd Passwd : teH0wLIpW0gyQ bsearch(二元搜索) 相关函数 qsort 表头文件 #include 定义函数 函数说明 附加说明 void *bsearch(const void *key,const void *base,size_t nmemb,size_t size,int (*compar) (const void*,const void*)); bsearch()利用二元搜索从排序好的数组中查找数据。参数 key 指 向欲查找的关键数据,参数 base 指向要被搜索的数组开头地址, 参数 nmemb 代表数组中的元素数量,每一元素的大小则由参数 size 决定,最后一项参数 compar 为一函数指针,这个函数用来判 断两个元素之间的大小关系,若传给 compar 的第一个参数所指的 元素数据大于第二个参数所指的元素数据则必须回传大于 0 的值, 两个元素数据相等则回传 0。 找到关键数据则返回找到的地址,如果在数组中找不到关键数据则 返回 NULL。 范例 #include #include #define NMEMB 5 #define SIZE 10 int compar(const void *a,const void *b) { return (strcmp((char *)a,(char *)b)); } main() { char data[50][size]={“linux”,”freebsd”,”solaris”,”sunos”,”windows”}; char key[80],*base ,*offset; int i, nmemb=NMEMB,size=SIZE; while(1){ printf(“>”); fgets(key,sizeof(key),stdin); key[strlen(key)-1]=’\0’; if(!strcmp(key,”exit”))break; if(!strcmp(key,”list”)){ for(i=0;ihello /*输入 hello 字符串*/ hello not found! /*找不到 hello 字符串*/ add hello to data array /*将 hello 字符串加入*/ >.list /*列出所有数据*/ freebsd linux solaris sunos windows hello >hello found: hello lfind(线性搜索) 相关函数 表头文件 定义函数 函数说明 lsearch #include void *lfind (const void *key,const void *base,size_t *nmemb,size_t size,int(* compar) (const void * ,const void *)); lfind(()利用线性搜索在数组中从头至尾一项项查找数据。参数 key 指向欲查找的关键数据,参数 base 指向要被搜索的数组开头地 址,参数 nmemb 代表数组中的元素数量,每一元素的大小则由参 数 size 决定,最后一项参数 compar 为一函数指针,这个函数用来 判断两个元素是否相同,若传给 compar 的异地个参数所指的元素 数据和第二个参数所指的元素数据相同时则返回 0,两个元素数据 不相同则返回非 0 值。lfind()与 lsearch()不同点在于,当找不 返回值 到关键数据时 lfind()仅会返回 NULL,而不会主动把该笔数据加入 数组尾端。 找到关键数据则返回找到的该笔元素的地址,如果在数组中找不到 关键数据则返回空指针(NULL)。 范例 参考 lsearch()。 lsearch(线性搜索) 相关函数 lfind 表头文件 定义函数 函数说明 返回值 #include void *lsearch(const void * key ,const void * base ,size_t * nmemb,size_t size, int ( * compar) (const void * ,const void *)); lsearch()利用线性搜索在数组中从头至尾一项项查找数据。参数 key 指向欲查找的关键数据,参数 base 指向要被搜索的数组开头地 址,参数 nmemb 代表数组中的元素数量,每一元素的大小则由参 数 size 决定,最后一项参数 compar 为一函数指针,这个函数用来 判断两个元素是否相同,若传给 compar 的第一个参数所指的元素 数据和第二个参数所指的元素数据相同时则返回 0,两个元素数据 不相同则返回非 0 值。如果 lsearch()找不到关键数据时会主动把 该项数据加入数组里。 找到关键数据则返回找到的该笔元素的四肢,如果在数组中找不到 关键数据则将此关键数据加入数组,再把加入数组后的地址返回。 范例 #include #include #define NMEMB 50 #define SIZE 10 int compar (comst void *a,const void *b) { return (strcmp((char *) a, (char *) b)); } main() { char data[NMEMB][SIZE]={“Linux”,”freebsd”,”solzris”,”sunos”,”windows”}; char key[80],*base,*offset; int i, nmemb=NMEMB,size=SIZE; for(i=1;i<5;i++){ fgets(key,sizeof9key),stdin); key[strlen(key)-1]=’\0’; base = data[0]; offset = (char *)lfind(key,base,&nmemb,size,compar); if(offset ==NULL){ printf(“%s not found!\n”,key); offset=(char *) lsearch(key,base,&nmemb,size,compar); printf(“Add %s to data array\n”,offset); }else{ printf(“found : %s \n”,offset); } } } 执行 linux found:linux os/2 os/2 not found! add os/2 to data array os/2 found : os/2 qsort(利用快速排序法排列数组) 相关函数 表头文件 定义函数 函数说明 返回值 bsearch #include void qsort(void * base,size_t nmemb,size_t size,int ( * compar)(const void *, const void *)); 参数 base 指向欲排序的数组开头地址,参数 nmemb 代表数组中的 元素数量,每一元素的大小则由参数 size 决定,最后一项参数 compar 为一函数指针,这个函数用来判断两个元素间的大小关系, 若传给 compar 的第一个参数所指的元素数据大于第二个参数所指 的元素数据则必须回传大于零的值,两个元素数据相等则回传 0。 无 附加说明 范例 #define nmemb 7 #include int compar (const void *a ,const void *b) { int *aa=(int * ) a,*bb = (int * )b; if( * aa >* bb)return 1; if( * aa == * bb) return 0; if( * aa < *bb) return -1; } main( ) { int base[nmemb]={ 3,102,5,-2,98,52,18}; int i; for ( i=0; i int rand(void) 函数说明 返回值 rand()会返回一随机数值,范围在 0 至 RAND_MAX 间。在调用 此函数产生随机数前,必须先利用 srand()设好随机数种子,如 果未设随机数种子,rand()在调用时会自动设随机数种子为 1。关 于随机数种子请参考 srand()。 返 回 0 至 RAND_MAX 之 间 的 随 机 数 值 , RAND_MAX 定 义 在 stdlib.h,其值为 2147483647。 范例 /* 产生介于 1 到 10 间的随机数值,此范例未设随机数种子,完整的随机数产生请参考 srand()*/ #include main() { int i,j; for(i=0;i<10;i++) { j=1+(int)(10.0*rand()/(RAND_MAX+1.0)); printf(“%d “,j); } } 执行 9 4 8 8 10 2 4 8 3 6 9 4 8 8 10 2 4 8 3 6 srand(设置随机数种子) 相关函数 表头文件 定义函数 函数说明 返回值 rand,random srandom #include void srand (unsigned int seed); srand() 用来设置 rand()产生随机数时的随机数种子。参数 seed 必 须是个整数,通常可以利用 geypid()或 time(0)的返回值来当 做 seed。如果每次 seed 都设相同值,rand()所产生的随机数值每 次就会一样。 无 范例 /* 产生介于 1 到 10 间的随机数值,此范例与执行结果可与 rand()参照*/ #include #include main() { int i,j; srand((int)time(0)); for(i=0;i<10;i++) { j=1+(int)(10.0*rand()/(RAND_MAX+1.0)); printf(“ %d “,j); } } 执行 5 8 8 8 10 2 10 8 9 9 2 9 7 4 10 3 2 10 8 7 close(关闭文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 附加说明 范例 open,fcntl,shutdown,unlink,fclose #include int close(int fd); 当使用完文件后若已不再需要则可使用 close()关闭该文件,二 close()会让数据写回磁盘,并释放该文件所占用的资源。参数 fd 为先前由 open()或 creat()所返回的文件描述词。 若文件顺利关闭则返回 0,发生错误时返回-1。 EBADF 参数 fd 非有效的文件描述词或该文件已关闭。 虽然在进程结束时,系统会自动关闭已打开的文件,但仍建议自行 关闭文件,并确实检查返回值。 参考 open() creat(建立文件) 相关函数 表头文件 定义函数 函数说明 错误代码 返回值 附加说明 read,write,fcntl,close,link,stat,umask,unlink,fopen #include #include #include int creat(const char * pathname, mode_tmode); 参数 pathname 指向欲建立的文件路径字符串。creat()相当于使用 下列的调用方式调用 open(): open(const char * pathname , (O_CREAT|O_WRONLY|O_TRUNC)); 关于参数 mode 请参考 open()函数。 creat() 会返回新的文件描述词,若有错误发生则会返回-1,并 把错误代码设给 errno。 EEXIST 参数 pathname 所指的文件已存在。 EACCESS 参数 pathname 所指定的文件不符合所要求测试的 权限 EROFS 欲打开写入权限的文件存在于只读文件系统内 EFAULT 参数 pathname 指针超出可存取的内存空间 EINVAL 参数 mode 不正确。 ENAMETOOLONG 参数 pathname 太长。 ENOTDIR 参数 pathname 为一目录 ENOMEM 核心内存不足 ELOOP 参数 pathname 有过多符号连接问题。 EMFILE 已达到进程可同时打开的文件数上限 ENFILE 已达到系统可同时打开的文件数上限 creat() 无法建立特别的装置文件,如果需要请使用 mknod()。 范例 请参考 open()。 dup(复制文件描述词) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 open,close,fcntl,dup2 #include int dup (int oldfd); dup()用来复制参数 oldfd 所指的文件描述词,并将它返回。此新 的文件描述词和参数 oldfd 指的是同一个文件,共享所有的锁定、读 写位置和各项权限或旗标。例如,当利用 lseek()对某个文件描述 词作用时,另一个文件描述词的读写位置也会随着改变。 不过,文件描述词之间并不共享 close-on-exec 旗标 当复制成功时,则返回最小及尚未使用的文件描述词。若有错误则 返回-1,errno 会存放错误代码。 EBADF 参数 fd 非有效的文件描述词,或该文件已关闭。 dup2(复制文件描述词) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 错误代码 open,close,fcntl,dup #include int dup2(int odlfd,int newfd); dup2()用来复制参数 oldfd 所指的文件描述词,并将它拷贝至参 数 newfd 后一块返回。若参数 newfd 为一已打开的文件描述词,则 newfd 所指的文件会先被关闭。dup2()所复制的文件描述词,与 原来的文件描述词共享各种文件状态,详情可参考 dup()。 当复制成功时,则返回最小及尚未使用的文件描述词。若有错误则 返回-1,errno 会存放错误代码。 dup2()相当于调用 fcntl(oldfd,F_DUPFD,newfd);请参考 fcntl()。 EBADF 参数 fd 非有效的文件描述词,或该文件已关闭 fcntl(文件描述词操作) 相关函数 表头文件 定义函数 函数说明 open,flock #include #include int fcntl(int fd , int cmd); int fcntl(int fd,int cmd,long arg); int fcntl(int fd,int cmd,struct flock * lock); fcntl()用来操作文件描述词的一些特性。参数 fd 代表欲设置的文 件描述词,参数 cmd 代表欲操作的指令,有以下几种情况: F_DUPFD 用来查找大于或等于参数 arg 的最小且仍未使用的文件 描述词,并且复制参数 fd 的文件描述词。执行成功则返回 新复制的文件描述词。请参考 dup2()。 F_GETFD 取得 close-on-exec 旗标。若此旗标的 FD_CLOEXEC 位 为 0,代表在调用 exec()相关函数时文件将不会关闭。 F_SETFD 设 置 close-on-exec 旗 标 。 该 旗 标 以 参 数 arg 的 FD_CLOEXEC 位决定。 F_GETFL 取得文件描述词状态旗标,此旗标为 open()的参数 flags。 F_SETFL 设置文件描述词状态旗标,参数 arg 为新旗标,但只允 许 O_APPEND、O_NONBLOCK 和 O_ASYNC 位的改变, 其他位的改变将不受影响。 F_GETLK 取得文件锁定的状态 F_SETLK 设置文件锁定的状态。此时 flcok 结构的 l_type 值必须是 F_RDLCK、F_WRLCK 或 F_UNLCK。如果无法建立锁定, 则返回-1,错误代码为 EACCES 或 EAGAIN。 F_SETLKW F_SETLK 作用相同,但是无法建立锁定时,此调用会 一直等到锁定动作成功为止。若在等待锁定的过程中被信 号中断时,会立即返回-1,错误代码为 EINTR。参数 lock 指针为 flock 结构指针,定义如下: struct flcok { short int l_type; /* 锁定的状态*/ short int l_whence;/*决定 l_start 位置*/ off_t l_start; /*锁定区域的开头位置*/ off_t l_len; /*锁定区域的大小*/ pid_t l_pid; /*锁定动作的进程*/ 返回值 }; l_type 有三种状态: F_RDLCK 建立一个供读取用的锁定 F_WRLCK 建立一个供写入用的锁定 F_UNLCK 删除之前建立的锁定 l_whence 也有三种方式: SEEK_SET 以文件开头为锁定的起始位置。 SEEK_CUR 以目前文件读写位置为锁定的起始位置 SEEK_END 以文件结尾为锁定的起始位置。 成功则返回 0,若有错误则返回-1,错误原因存于 errno. flock(锁定文件或解除锁定) 相关函数 表头文件 定义函数 函数说明 返回值 open,fcntl #include int flock(int fd,int operation); flock()会依参数 operation 所指定的方式对参数 fd 所指的文件做 各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定 文件的某一区域。 参数 operation 有下列四种情况: LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁 定。 LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。 LOCK_UN 解除文件锁定状态。 LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。 通常与 LOCK_SH 或 LOCK_EX 做 OR(|)组合。 单一文件无法同时建立共享锁定和互斥锁定,而当使用 dup()或 fork()时文件描述词不会继承此种锁定。 返回 0 表示成功,若有错误则返回-1,错误代码存于 errno。 fsync(将缓冲区数据写回磁盘) 相关函数 表头文件 定义函数 函数说明 返回值 sync #include int fsync(int fd); fsync()负责将参数 fd 所指的文件数据,由系统缓冲区写回磁盘, 以确保数据同步。 成功则返回 0,失败返回-1,errno 为错误代码 lseek(移动文件的读写位置) 相关函数 表头文件 定义函数 函数说明 dup,open,fseek #include #include off_t lseek(int fildes,off_t offset ,int whence); 每一个已打开的文件都有一个读写位置,当打开文件时通常其读写 位置是指向文件开头,若是以附加的方式打开文件(如 O_APPEND ) , 则 读 写 位 置 会 指 向 文 件 尾 。 当 read ( ) 或 write()时,读写位置会随之增加,lseek()便是用来控制该文件 的读写位置。参数 fildes 为已打开的文件描述词,参数 offset 为根据 参数 whence 来移动读写位置的位移数。参数 whence 为下列其中一 种: SEEK_SET 参数 offset 即为新的读写位置。 SEEK_CUR 以目前的读写位置往后增加 offset 个位移量。 SEEK_END 将读写位置指向文件尾后再增加 offset 个位移量。 当 whence 值为 SEEK_CUR 或 SEEK_END 时,参数 offet 允许负值 的出现。 下列是教特别的使用方式: 1) 欲 将 读 写 位 置 移 到 文 件 开 头 时 : lseek ( int fildes,0,SEEK_SET); 2) 欲 将 读 写 位 置 移 到 文 件 尾 时 : lseek ( int fildes,0,SEEK_END); 3) 想要取得目前文件位置时:lseek(int fildes,0,SEEK_CUR); 返回值 附加说明 范例 参考本函数说明 当调用成功时则返回目前的读写位置,也就是距离文件开头多少个 字节。若有错误则返回-1,errno 会存放错误代码。 Linux 系 统 不 允 许 lseek ( ) 对 tty 装 置 作 用 , 此 项 动 作 会 令 lseek()返回 ESPIPE。 mkstemp(建立唯一的临时文件) 相关函数 表头文件 定义函数 mktemp #include int mkstemp(char * template); 函数说明 错误代码 附加说明 范例 #include mkstemp()用来建立唯一的临时文件。参数 template 所指的文件名 称字符串中最后六个字符必须是 XXXXXX。mkstemp()会以可读 写模式和 0600 权限来打开该文件,如果该文件不存在则会建立该 文件。打开该文件后其文件描述词会返回。 文件顺利打开后返回可读写的文件描述词。若果文件打开失败则返 回 NULL,并把错误代码存在 errno 中。 EINVAL 参数 template 字符串最后六个字符非 XXXXXX。 EEXIST 无法建立临时文件。 参数 template 所指的文件名称字符串必须声明为数组,如: char template[ ] =”template-XXXXXX”; 千万不可以使用下列的表达方式 char *template = “template-XXXXXX”; main( ) { int fd; char template[ ]=”template-XXXXXX”; fd=mkstemp(template); printf(“template = %s\n”,template); close(fd); } 执行 template = template-lgZcbo open(打开文件) 相关函数 表头文件 定义函数 函数说明 read,write,fcntl,close,link,stat,umask,unlink,fopen #include #include #include int open( const char * pathname, int flags); int open( const char * pathname,int flags, mode_t mode); 参数 pathname 指向欲打开的文件路径字符串。下列是参数 flags 所 能使用的旗标: O_RDONLY 以只读方式打开文件 O_WRONLY 以只写方式打开文件 O_RDWR 以可读写方式打开文件。上述三种旗标是互斥的,也就 是不可同时使用,但可与下列的旗标利用 OR(|)运算符组合。 O_CREAT 若欲打开的文件不存在则自动建立该文件。 O_EXCL 如果 O_CREAT 也被设置,此指令会去检查文件是否存 在。文件若不存在则建立该文件,否则将导致打开文件错误。此外, 若 O_CREAT 与 O_EXCL 同时设置,并且欲打开的文件为符号连接, 则会打开文件失败。 O_NOCTTY 如果欲打开的文件为终端机设备时,则不会将该终端 机当成进程控制终端机。 O_TRUNC 若文件存在并且以可写的方式打开时,此旗标会令文件 长度清为 0,而原来存于该文件的资料也会消失。 O_APPEND 当读写文件时会从文件尾开始移动,也就是所写入的 数据会以附加的方式加入到文件后面。 O_NONBLOCK 以不可阻断的方式打开文件,也就是无论有无数 据读取或等待,都会立即返回进程之中。 O_NDELAY 同 O_NONBLOCK。 O_SYNC 以同步的方式打开文件。 O_NOFOLLOW 如果参数 pathname 所指的文件为一符号连接,则 会令打开文件失败。 O_DIRECTORY 如果参数 pathname 所指的文件并非为一目录,则 会令打开文件失败。此为 Linux2.2 以后特有的旗标,以避免一些系 返回值 错误代码 附加说明 范例 统安全问题。参数 mode 则有下列数种组合,只有在建立新文件时 才会生效,此外真正建文件时的权限会受到 umask 值所影响,因此 该文件权限应该为(mode-umaks). S_IRWXU00700 权限,代表该文件所有者具有可读、可写及可执行 的权限。 S_IRUSR 或 S_IREAD,00400 权限,代表该文件所有者具有可读 取的权限。 S_IWUSR 或 S_IWRITE,00200 权限,代表该文件所有者具有可 写入的权限。 S_IXUSR 或 S_IEXEC,00100 权限,代表该文件所有者具有可执 行的权限。 S_IRWXG 00070 权限,代表该文件用户组具有可读、可写及可执行 的权限。 S_IRGRP 00040 权限,代表该文件用户组具有可读的权限。 S_IWGRP 00020 权限,代表该文件用户组具有可写入的权限。 S_IXGRP 00010 权限,代表该文件用户组具有可执行的权限。 S_IRWXO 00007 权限,代表其他用户具有可读、可写及可执行的权 限。 S_IROTH 00004 权限,代表其他用户具有可读的权限 S_IWOTH 00002 权限,代表其他用户具有可写入的权限。 S_IXOTH 00001 权限,代表其他用户具有可执行的权限。 若所有欲核查的权限都通过了检查则返回 0 值,表示成功,只要有 一个权限被禁止则返回-1。 EEXIST 参数 pathname 所指的文件已存在,却使用了 O_CREAT 和 O_EXCL 旗标 EACCESS 参数 pathname 所指的文件不符合所要求测试的权限。 EROFS 欲测试写入权限的文件存在于只读文件系统内。 EFAULT 参数 pathname 指针超出可存取内存空间。 EINVAL 参数 mode 不正确。 ENAMETOOLONG 参数 pathname 太长。 ENOTDIR 参数 pathname 不是目录。 ENOMEM 核心内存不足。 ELOOP 参数 pathname 有过多符号连接问题。 EIO I/O 存取错误。 使 用 access ( ) 作 用 户 认 证 方 面 的 判 断 要 特 别 小 心 , 例 如 在 access()后再作 open()空文件可能会造成系统安全上的问题。 #include #include #include #include main() { int fd,size; char s [ ]=”Linux Programmer!\n”,buffer[80]; fd=open(“/tmp/temp”,O_WRONLY|O_CREAT); write(fd,s,sizeof(s)); close(fd); fd=open(“/tmp/temp”,O_RDONLY); size=read(fd,buffer,sizeof(buffer)); close(fd); printf(“%s”,buffer); } 执行 Linux Programmer! read(由已打开的文件读取数据) 相关函数 表头文件 定义函数 函数说明 附加说明 错误代码 readdir,write,fcntl,close,lseek,readlink,fread #include ssize_t read(int fd,void * buf ,size_t count); read()会把参数 fd 所指的文件传送 count 个字节到 buf 指针所指 的内存中。若参数 count 为 0,则 read()不会有作用并返回 0。返回 值为实际读取到的字节数,如果返回 0,表示已到达文件尾或是无 可读取的数据,此外文件读写位置会随读取到的字节移动。 如果顺利 read()会返回实际读到的字节数,最好能将返回值与参 数 count 作比较,若返回的字节数比要求读取的字节数少,则有可 能读到了文件尾、从管道(pipe)或终端机读取,或者是 read() 被信号中断了读取动作。当有错误发生时则返回-1,错误代码存入 errno 中,而文件读写位置则无法预期。 EINTR 此调用被信号所中断。 EAGAIN 当使用不可阻断 I/O 时(O_NONBLOCK),若无数据可 读取则返回此值。 EBADF 参数 fd 非有效的文件描述词,或该文件已关闭。 范例 参考 open()。 sync(将缓冲区数据写回磁盘) 相关函数 表头文件 定义函数 函数说明 返回值 fsync #include int sync(void) sync()负责将系统缓冲区数据写回磁盘,以确保数据同步。 返回 0。 write(将数据写入已打开的文件内) 相关函数 open,read,fcntl,close,lseek,sync,fsync,fwrite 表头文件 #include 定义函数 ssize_t write (int fd,const void * buf,size_t count); 函数说明 返回值 错误代码 write()会把参数 buf 所指的内存写入 count 个字节到参数 fd 所指 的文件内。当然,文件读写位置也会随之移动。 如果顺利 write()会返回实际写入的字节数。当有错误发生时则返 回-1,错误代码存入 errno 中。 EINTR 此调用被信号所中断。 EAGAIN 当使用不可阻断 I/O 时(O_NONBLOCK),若无数据可 读取则返回此值。 EADF 参数 fd 非有效的文件描述词,或该文件已关闭。 范例 请参考 open()。 clearerr(清除文件流的错误旗标) 相关函数 表头文件 定义函数 函数说明 返回值 feof #include void clearerr(FILE * stream); clearerr()清除参数 stream 指定的文件流所使用的错误旗标。 无 fclose(关闭文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 close,fflush,fopen,setbuf #include int fclose(FILE * stream); fclose()用来关闭先前 fopen()打开的文件。此动作会让缓冲区 内的数据写入文件中,并释放系统所提供的文件资源。 若关文件动作成功则返回 0,有错误发生时则返回 EOF 并把错误代 码存到 errno。 EBADF 表示参数 stream 非已打开的文件。 范例 请参考 fopen()。 fdopen(将文件描述词转为文件指针) 相关函数 fopen,open,fclose 表头文件 定义函数 #include FILE * fdopen(int fildes,const char * mode); 函数说明 返回值 fdopen()会将参数 fildes 的文件描述词,转换为对应的文件指针 后返回。参数 mode 字符串则代表着文件指针的流形态,此形态必 须和原先文件描述词读写模式相同。关于 mode 字符串格式请参考 fopen()。 转换成功时返回指向该流的文件指针。失败则返回 NULL,并把错 误代码存在 errno 中。 范例 #include main() { FILE * fp =fdopen(0,”w+”); fprintf(fp,”%s\n”,”hello!”); fclose(fp); } 执行 hello! feof(检查文件流是否读到了文件尾) 相关函数 表头文件 定义函数 函数说明 返回值 fopen,fgetc,fgets,fread #include int feof(FILE * stream); feof()用来侦测是否读取到了文件尾,尾数 stream 为 fopen() 所返回之文件指针。如果已到文件尾则返回非零值,其他情况返回 0。 返回非零值代表已到达文件尾。 fflush(更新缓冲区) 相关函数 write,fopen,fclose,setbuf 表头文件 定义函数 函数说明 返回值 错误代码 #include int fflush(FILE* stream); fflush()会强迫将缓冲区内的数据写回参数 stream 指定的文件中。 如果参数 stream 为 NULL,fflush()会将所有打开的文件数据更 新。 成功返回 0,失败返回 EOF,错误代码存于 errno 中。 EBADF 参数 stream 指定的文件未被打开,或打开状态为只读。其 它错误代码参考 write()。 fgetc(由文件中读取一个字符) 相关函数 表头文件 定义函数 函数说明 返回值 fopen,fread,fscanf,getc #include int fgetc(FILE * stream); fgetc()用来从参数 stream 所指的文件中读取一个字符。若读到文 件尾而无数据时便返回 EOF。 fgetc()会返回读取到的字符,若返回 EOF 则表示到了文件尾。 范例 #include main() { FILE *fp; int c; fp=fopen(“exist”,”r”); while((c=fgetc(fp))!=EOF) printf(“%c”,c); fclose(fp); } fgets(由文件中读取一字符串) 相关函数 表头文件 定义函数 函数说明 返回值 fopen,fread,fscanf,getc #include char * fgets(char * s,int size,FILE * stream); fgets()用来从参数 stream 所指的文件内读入字符并存到参数 s 所 指的内存空间,直到出现换行字符、读到文件尾或是已读了 size-1 个字符为止,最后会加上 NULL 作为字符串结束。 fgets()若成功则返回 s 指针,返回 NULL 则表示有错误发生。 范例 #include main() { char s[80]; fputs(fgets(s,80,stdin),stdout); } 执行 this is a test /*输入*/ this is a test /*输出*/ fileno(返回文件流所使用的文件描述词) 相关函数 表头文件 定义函数 函数说明 返回值 open,fopen #include int fileno(FILE * stream); fileno()用来取得参数 stream 指定的文件流所使用的文件描述词。 返回文件描述词。 范例 #include main() { FILE * fp; int fd; fp=fopen(“/etc/passwd”,”r”); fd=fileno(fp); printf(“fd=%d\n”,fd); fclose(fp); } 执行 fd=3 fopen(打开文件) 相关函数 表头文件 定义函数 函数说明 open,fclose #include FILE * fopen(const char * path,const char * mode); 参数 path 字符串包含欲打开的文件路径及文件名,参数 mode 字符 串则代表着流形态。mode 有下列几种形态字符串: r 打开只读文件,该文件必须存在。 r+ 打开可读写的文件,该文件必须存在。 w 打开只写文件,若文件存在则文件长度清为 0,即该文件内容 会消失。若文件不存在则建立该文件。 w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内 容会消失。若文件不存在则建立该文件。 a 以附加的方式打开只写文件。若文件不存在,则会建立该文件, 如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会 被保留。 a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件, 如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容 会被保留。 上述的形态字符串都可以再加一个 b 字符,如 rb、w+b 或 ab+等组 合,加入 b 字符用来告诉函数库打开的文件为二进制文件,而非纯 文字文件。不过在 POSIX 系统,包含 Linux 都会忽略该字符。由 fopen ( ) 所 建 立 的 新 文 件 会 具 有 S_IRUSR|S_IWUSR|S_IRGRP| 返回值 附加说明 S_IWGRP|S_IROTH|S_IWOTH ( 0666 ) 权 限 , 此 文 件 权 限 也 会 参 考 umask 值。 文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开 失败则返回 NULL,并把错误代码存在 errno 中。 一般而言,开文件后会作一些文件读取或写入的动作,若开文件失 败,接下来的读写动作也无法顺利进行,所以在 fopen()后请作 错误判断及处理。 范例 #include main() { FILE * fp; fp=fopen(“noexist”,”a+”); if(fp= =NULL) return; fclose(fp); } fputc(将一指定字符写入文件流中) 相关函数 表头文件 定义函数 函数说明 返回值 fopen,fwrite,fscanf,putc #include int fputc(int c,FILE * stream); fputc 会将参数 c 转为 unsigned char 后写入参数 stream 指定的文件 中。 fputc()会返回写入成功的字符,即参数 c。若返回 EOF 则代表写 入失败。 范例 #include main() { FILE * fp; char a[26]=”abcdefghijklmnopqrstuvwxyz”; int i; fp= fopen(“noexist”,”w”); for(i=0;i<26;i++) fputc(a[i],fp); fclose(fp);} fputs(将一指定的字符串写入文件内) 相关函数 表头文件 定义函数 函数说明 返回值 fopen,fwrite,fscanf,fputc,putc #include int fputs(const char * s,FILE * stream); fputs()用来将参数 s 所指的字符串写入到参数 stream 所指的文件 内。 若成功则返回写出的字符个数,返回 EOF 则表示有错误发生。 范例 请参考 fgets()。 fread(从文件流读取数据) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 fopen,fwrite,fseek,fscanf #include size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream); fread()用来从文件流中读取数据。参数 stream 为已打开的文件指 针,参数 ptr 指向欲存放读取进来的数据空间,读取的字符数以参 数 size*nmemb 来决定。fread()会返回实际读取到的 nmemb 数目, 如果此值比参数 nmemb 来得小,则代表可能读到了文件尾或有错 误发生,这时必须用 feof()或 ferror()来决定发生什么情况。 返回实际读取到的 nmemb 数目。 范例 #include #define nmemb 3 struct test { char name[20]; int size; }s[nmemb]; main() { FILE * stream; int i; stream = fopen(“/tmp/fwrite”,”r”); fread(s,sizeof(struct test),nmemb,stream); fclose(stream); for(i=0;i FILE * freopen(const char * path,const char * mode,FILE * stream); 参数 path 字符串包含欲打开的文件路径及文件名,参数 mode 请参 考 fopen()说明。参数 stream 为已打开的文件指针。freopen()会 将原 stream 所打开的文件流关闭,然后打开参数 path 的文件。 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开 失败则返回 NULL,并把错误代码存在 errno 中。 范例 #include main() { FILE * fp; fp=fopen(“/etc/passwd”,”r”); fp=freopen(“/etc/group”,”r”,fp); fclose(fp); } fseek(移动文件流的读写位置) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 范例 rewind,ftell,fgetpos,fsetpos,lseek #include int fseek(FILE * stream,long offset,int whence); fseek()用来移动文件流的读写位置。参数 stream 为已打开的文件 指针,参数 offset 为根据参数 whence 来移动读写位置的位移数。参 数 whence 为下列其中一种:SEEK_SET 从距文件开头 offset 位移量 为新的读写位置。SEEK_CUR 以目前的读写位置往后增加 offset 个 位移量。SEEK_END 将读写位置指向文件尾后再增加 offset 个位移 量。 当 whence 值为 SEEK_CUR 或 SEEK_END 时,参数 offset 允许负值 的出现。下列是较特别的使用方式: 1) 欲 将 读 写 位 置 移 动 到 文 件 开 头 时 : fseek(FILE * stream,0,SEEK_SET); 2) 欲 将 读 写 位 置 移 动 到 文 件 尾 时 : fseek(FILE * stream,0,0SEEK_END); 当调用成功时则返回 0,若有错误则返回-1,errno 会存放错误代码。 fseek()不像 lseek()会返回读写位置,因此必须使用 ftell() 来取得目前读写的位置。 #include main() { FILE * stream; long offset; fpos_t pos; stream=fopen(“/etc/passwd”,”r”); fseek(stream,5,SEEK_SET); printf(“offset=%d\n”,ftell(stream)); rewind(stream); fgetpos(stream,&pos); printf(“offset=%d\n”,pos); pos=10; fsetpos(stream,&pos); printf(“offset = %d\n”,ftell(stream)); fclose(stream); } 执行 offset = 5 offset =0 offset=10 ftell(取得文件流的读取位置) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 fseek,rewind,fgetpos,fsetpos #include long ftell(FILE * stream); ftell()用来取得文件流目前的读写位置。参数 stream 为已打开的 文件指针。 当调用成功时则返回目前的读写位置,若有错误则返回 -1,errno 会存放错误代码。 EBADF 参数 stream 无效或可移动读写位置的文件流。 范例 参考 fseek()。 fwrite(将数据写至文件流) 相关函数 表头文件 定义函数 函数说明 返回值 fopen,fread,fseek,fscanf #include size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream); fwrite()用来将数据写入文件流中。参数 stream 为已打开的文件指 针,参数 ptr 指向欲写入的数据地址,总共写入的字符数以参数 size*nmemb 来决定。fwrite()会返回实际写入的 nmemb 数目。 返回实际写入的 nmemb 数目。 范例 #include #define set_s (x,y) {strcoy(s[x].name,y);s[x].size=strlen(y);} #define nmemb 3 struct test { char name[20]; int size; }s[nmemb]; main() { FILE * stream; set_s(0,”Linux!”); set_s(1,”FreeBSD!”); set_s(2,”Windows2000.”); stream=fopen(“/tmp/fwrite”,”w”); fwrite(s,sizeof(struct test),nmemb,stream); fclose(stream); } 执行 参考 fread()。 getc(由文件中读取一个字符) 相关函数 表头文件 定义函数 函数说明 返回值 read,fopen,fread,fgetc #include int getc(FILE * stream); getc()用来从参数 stream 所指的文件中读取一个字符。若读到文 件尾而无数据时便返回 EOF。虽然 getc()与 fgetc()作用相同, 但 getc()为宏定义,非真正的函数调用。 getc()会返回读取到的字符,若返回 EOF 则表示到了文件尾。 范例 参考 fgetc()。 getchar(由标准输入设备内读进一字符) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 fopen,fread,fscanf,getc #include int getchar(void); getchar()用来从标准输入设备中读取一个字符。然后将该字符从 unsigned char 转换成 int 后返回。 getchar()会返回读取到的字符,若返回 EOF 则表示有错误发生。 getchar()非真正函数,而是 getc(stdin)宏定义。 范例 #include main() { FILE * fp; int c,i; for(i=0li<5;i++) { c=getchar(); putchar(c); } } 执行 1234 /*输入*/ 1234 /*输出*/ gets(由标准输入设备内读进一字符串) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 范例 参考 fgets() fopen,fread,fscanf,fgets #include char * gets(char *s); gets()用来从标准设备读入字符并存到参数 s 所指的内存空间, 直到出现换行字符或读到文件尾为止,最后加上 NULL 作为字符串 结束。 gets()若成功则返回 s 指针,返回 NULL 则表示有错误发生。 由于 gets()无法知道字符串 s 的大小,必须遇到换行字符或文件 尾才会结束输入,因此容易造成缓冲溢出的安全性问题。建议使用 fgets()取代。 mktemp(产生唯一的临时文件名) 相关函数 tmpfile 表头文件 #include 定义函数 char * mktemp(char * template); 函数说明 返回值 附加说明 mktemp()用来产生唯一的临时文件名。参数 template 所指的文件 名称字符串中最后六个字符必须是 XXXXXX。产生后的文件名会借 字符串指针返回。 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开 失败则返回 NULL,并把错误代码存在 errno 中。 参数 template 所指的文件名称字符串必须声明为数组,如 char template[ ]=”template-XXXXXX”;不可用 char * template=”templateXXXXXX”; 范例 #include main() { char template[ ]=”template-XXXXXX”; mktemp(template); printf(“template=%s\n”,template); } putc(将一指定字符写入文件中) 相关函数 表头文件 定义函数 函数说明 返回值 范例 参考 fputc()。 fopen,fwrite,fscanf,fputc #include int putc(int c,FILE * stream); putc()会将参数 c 转为 unsigned char 后写入参数 stream 指定的文 件中。虽然 putc()与 fputc()作用相同,但 putc()为宏定义, 非真正的函数调用。 putc()会返回写入成功的字符,即参数 c。若返回 EOF 则代表写 入失败。 putchar(将指定的字符写到标准输出设备) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 fopen,fwrite,fscanf,fputc #include int putchar (int c); putchar()用来将参数 c 字符写到标准输出设备。 putchar()会返回输出成功的字符,即参数 c。若返回 EOF 则代表 输出失败。 putchar()非真正函数,而是 putc(c,stdout)宏定义。 范例 参考 getchar()。 rewind(重设文件流的读写位置为文件开头) 相关函数 表头文件 定义函数 函数说明 返回值 fseek,ftell,fgetpos,fsetpos #include void rewind(FILE * stream); rewind()用来把文件流的读写位置移至文件开头。参数 stream 为 已打开的文件指针。此函数相当于调用 fseek(stream,0,SEEK_SET)。 无 范例 参考 fseek() setbuf(设置文件流的缓冲区) 相关函数 setbuffer,setlinebuf,setvbuf 表头文件 定义函数 函数说明 返回值 #include void setbuf(FILE * stream,char * buf); 在打开文件流后,读取内容之前,调用 setbuf()可以用来设置文 件流的缓冲区。参数 stream 为指定的文件流,参数 buf 指向自定的 缓 冲 区 起 始 地 址 。 如 果 参 数 buf 为 NULL 指 针 , 则 为 无 缓 冲 IO 。 setbuf ( ) 相 当 于 调 用 : setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ); 无 setbuffer(设置文件流的缓冲区) 相关函数 表头文件 定义函数 函数说明 返回值 setlinebuf,setbuf,setvbuf #include void setbuffer(FILE * stream,char * buf,size_t size); 在打开文件流后,读取内容之前,调用 setbuffer()可用来设置文 件流的缓冲区。参数 stream 为指定的文件流,参数 buf 指向自定的 缓冲区起始地址,参数 size 为缓冲区大小。 无 setlinebuf(设置文件流为线性缓冲区) 相关函数 表头文件 定义函数 函数说明 返回值 setbuffer,setbuf,setvbuf #include void setlinebuf(FILE * stream); setlinebuf()用来设置文件流以换行为依据的无缓冲 IO。相当于调 用:setvbuf(stream,(char * )NULL,_IOLBF,0);请参考 setvbuf()。 无 setvbuf(设置文件流的缓冲区) 相关函数 表头文件 定义函数 函数说明 返回值 setbuffer,setlinebuf,setbuf #include int setvbuf(FILE * stream,char * buf,int mode,size_t size); 在打开文件流后,读取内容之前,调用 setvbuf()可以用来设置 文件流的缓冲区。参数 stream 为指定的文件流,参数 buf 指向自定 的缓冲区起始地址,参数 size 为缓冲区大小,参数 mode 有下列几 种: _IONBF 无缓冲 IO _IOLBF 以换行为依据的无缓冲 IO _IOFBF 完全无缓冲 IO。如果参数 buf 为 NULL 指针,则为无缓冲 IO。 无 ungetc(将指定字符写回文件流中) 相关函数 表头文件 定义函数 函数说明 返回值 fputc,getchar,getc #include int ungetc(int c,FILE * stream); ungetc()将参数 c 字符写回参数 stream 所指定的文件流。这个写回 的字符会由下一个读取文件流的函数取得。 成功则返回 c 字符,若有错误则返回 EOF。 atexit(设置程序正常结束前调用的函数) 相关函数 _exit,exit,on_exit 表头文件 定义函数 函数说明 返回值 #include int atexit (void (*function)(void)); atexit()用来设置一个程序正常结束前调用的函数。当程序通过调 用 exit()或从 main 中返回时,参数 function 所指定的函数会先被 调用,然后才真正由 exit()结束程序。 如果执行成功则返回 0,否则返回-1,失败原因存于 errno 中。 范例 #include void my_exit(void) { printf(“before exit () !\n”); } main() { atexit (my_exit); exit(0); } 执行 before exit()! execl(执行文件) 相关函数 表头文件 定义函数 函数说明 返回值 范例 fork,execle,execlp,execv,execve,execvp #include int execl(const char * path,const char * arg,....); execl()用来执行参数 path 字符串所代表的文件路径,接下来的 参数代表执行该文件时传递过去的 argv〔0〕、argv[1]……,最后一个 参数必须用空指针(NULL)作结束。 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因 存于 errno 中。 #include main() { execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char * )0); } 执行 /*执行/bin/ls -al /etc/passwd */ -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd execlp(从 PATH 环境变量中查找文件并执行) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 fork,execl,execle,execv,execve,execvp #include int execlp(const char * file,const char * arg,……); execlp()会从 PATH 环境变量所指的目录中查找符合参数 file 的 文件名,找到后便执行该文件,然后将第二个以后的参数当做该文 件的 argv[0]、argv[1]……,最后一个参数必须用空指针(NULL) 作结束。 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因 存于 errno 中。 参考 execve()。 范例 /* 执行 ls -al /etc/passwd execlp()会依 PATH 变量中的/bin 找到/bin/ls */ #include main() { execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0); } 执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd execv(执行文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 fork,execl,execle,execlp,execve,execvp #include int execv (const char * path, char * const argv[ ]); execv ( ) 用 来 执 行 参 数 path 字 符 串 所 代 表 的 文 件 路 径 , 与 execl()不同的地方在于 execve()只需两个参数,第二个参数利 用数组指针来传递给执行文件。 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因 存于 errno 中。 请参考 execve()。 范例 /* 执行 /bin/ls -al /etc/passwd */ #include main() { char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char*) }}; execv(“/bin/ls”,argv); } 执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd execve(执行文件) 相关函数 表头文件 定义函数 函数说明 fork,execl,execle,execlp,execv,execvp #include int execve(const char * filename,char * const argv[ ],char * const envp[ ]); execve()用来执行参数 filename 字符串所代表的文件路径,第二 个参数系利用数组指针来传递给执行文件,最后一个参数则为传递 给执行文件的新环境变量数组。 返回值 错误代码 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因 存于 errno 中。 EACCES 1. 欲执行的文件不具有用户可执行的权限。 2. 欲执行的文件所属的文件系统是以 noexec 方式挂上。 3.欲执行的文件或 script 翻译器非一般文件。 EPERM 1.进程处于被追踪模式,执行者并不具有 root 权限,欲 执行的文件具有 SUID 或 SGID 位。 2.欲执行的文件所属的文件系统是以 nosuid 方式挂 上,欲执行的文件具有 SUID 或 SGID 位元,但执行 者并不具有 root 权限。 E2BIG 参数数组过大 ENOEXEC 无法判断欲执行文件的执行文件格式,有可能是格式 错误或无法在此平台执行。 EFAULT 参数 filename 所指的字符串地址超出可存取空间范 围。 ENAMETOOLONG 参数 filename 所指的字符串太长。 ENOENT 参数 filename 字符串所指定的文件不存在。 ENOMEM 核心内存不足 ENOTDIR 参数 filename 字符串所包含的目录路径并非有效目录 EACCES 参数 filename 字符串所包含的目录路径无法存取,权 限不足 ELOOP 过多的符号连接 ETXTBUSY 欲执行的文件已被其他进程打开而且正把数据写入该 文件中 EIO I/O 存取错误 ENFILE 已达到系统所允许的打开文件总数。 EMFILE 已达到系统所允许单一进程所能打开的文件总数。 EINVAL 欲执行文件的 ELF 执行格式不只一个 PT_INTERP 节区 EISDIR ELF 翻译器为一目录 ELIBBAD ELF 翻译器有问题。 范例 #include main() { char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char *)0}; char * envp[ ]={“PATH=/bin”,0} execve(“/bin/ls”,argv,envp); } 执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd execvp(执行文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 fork,execl,execle,execlp,execv,execve #include int execvp(const char *file ,char * const argv []); execvp()会从 PATH 环境变量所指的目录中查找符合参数 file 的 文件名,找到后便执行该文件,然后将第二个参数 argv 传给该欲 执行的文件。 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因 存于 errno 中。 请参考 execve()。 范例 /*请与 execlp()范例对照*/ #include main() { char * argv[ ] ={ “ls”,”-al”,”/etc/passwd”,0}; execvp(“ls”,argv); } 执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd exit(正常结束进程) 相关函数 _exit,atexit,on_exit 表头文件 定义函数 函数说明 返回值 范例 参考 wait() #include void exit(int status); exit()用来正常终结目前进程的执行,并把参数 status 返回给父进程, 而进程所有的缓冲区数据会自动写回并关闭未关闭的文件。 无 _exit(结束进程执行) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 exit,wait,abort #include void _exit(int status); _exit()用来立刻结束目前进程的执行,并把参数 status 返回给父 进程,并关闭未关闭的文件。此函数调用后不会返回,并且会传递 SIGCHLD 信号给父进程,父进程可以由 wait 函数取得子进程结束 状态。 无 _exit ( ) 不 会 处 理 标 准 I/O 缓 冲 区 , 如 要 更 新 缓 冲 区 请 使 用 exit()。 vfork(建立一个新的进程) 相关函数 表头文件 定义函数 wait,execve #include pid_t vfork(void); 函数说明 返回值 错误代码 vfork()会产生一个新的子进程,其子进程会复制父进程的数据 与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打 开 的 文 件 代 码 、 工 作 目 录 和 资 源 限 制 等 。 Linux 使 用 copy-onwrite(COW)技术,只有当其中一进程试图修改欲复制的空间时 才会做真正的复制动作,由于这些继承的信息是复制而来,并非指 相同的内存空间,因此子进程对这些变量的修改和父进程并不会同 步。此外,子进程不会继承父进程的文件锁定和未处理的信号。注意, Linux 不保证子进程会比父进程先执行或晚执行,因此编写程序时 要留意死锁或竞争条件的发生。 如 果 vfork ( ) 成 功 则 在 父 进 程 会 返 回 新 建 立 的 子 进 程 代 码 (PID),而在新建立的子进程中则返回 0。如果 vfork 失败则直接 返回-1,失败原因存于 errno 中。 EAGAIN 内存不足 ENOMEM 内存不足,无法配置核心所需的数据结构空间。 范例 #include main() { if(vfork() = =0) { printf(“This is the child process\n”); }else{ printf(“This is the parent process\n”); } } 执行 this is the parent process this is the child process getpgid(取得进程组识别码) 相关函数 表头文件 定义函数 setpgid,setpgrp,getpgrp #include pid_t getpgid( pid_t pid); 函数说明 返回值 错误代码 getpgid()用来取得参数 pid 指定进程所属的组识别码。如果参数 pid 为 0,则会取得目前进程的组识别码。 执行成功则返回组识别码,如果有错误则返回-1,错误原因存于 errno 中。 ESRCH 找不到符合参数 pid 指定的进程。 范例 /*取得 init 进程(pid=1)的组识别码*/ #include mian() { printf(“init gid = %d\n”,getpgid(1)); } 执行 init gid = 0 getpgrp(取得进程组识别码) 相关函数 表头文件 定义函数 函数说明 返回值 setpgid,getpgid,getpgrp #include pid_t getpgrp(void); getpgrp()用来取得目前进程所属的组识别码。此函数相当于调用 getpgid(0); 返回目前进程所属的组识别码。 范例 #include main() { printf(“my gid =%d\n”,getpgrp()); } 执行 my gid =29546 getpid(取得进程识别码) 相关函数 表头文件 定义函数 函数说明 返回值 fork,kill,getpid #include pid_t getpid(void); getpid()用来取得目前进程的进程识别码,许多程序利用取到的 此值来建立临时文件,以避免临时文件相同带来的问题。 目前进程的进程识别码 范例 #include main() { printf(“pid=%d\n”,getpid()); } 执行 pid=1494 /*每次执行结果都不一定相同*/ getppid(取得父进程的进程识别码) 相关函数 表头文件 定义函数 函数说明 返回值 fork,kill,getpid #include pid_t getppid(void); getppid()用来取得目前进程的父进程识别码。 目前进程的父进程识别码。 范例 #include main() { printf(“My parent ‘pid =%d\n”,getppid()); } 执行 My parent ‘pid =463 getpriority(取得程序进程执行优先权) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 错误代码 setpriority,nice #include #include int getpriority(int which,int who); getpriority()可用来取得进程、进程组和用户的进程执行优先权。 参数 which 有三种数值,参数 who 则依 which 值有不同定义: which who 代表的意义 PRIO_PROCESS who 为进程识别码 PRIO_PGRP who 为进程的组识别码 PRIO_USER who 为用户识别码 此函数返回的数值介于-20 至 20 之间,代表进程执行优先权,数值 越低代表有较高的优先次序,执行会较频繁。 返回进程执行优先权,如有错误发生返回值则为-1 且错误原因存于 errno。 由于返回值有可能是-1,因此要同时检查 errno 是否存有错误原因。 最好在调用次函数前先清除 errno 变量。 ESRCH 参数 which 或 who 可能有错,而找不到符合的进程 EINVAL 参数 which 值错误。 nice(改变进程优先顺序) 相关函数 setpriority,getpriority 表头文件 定义函数 函数说明 返回值 错误代码 #include int nice(int inc); nice()用来改变进程的进程执行优先顺序。参数 inc 数值越大则优 先顺序排在越后面,即表示进程执行会越慢。只有超级用户才能使 用负的 inc 值,代表优先顺序排在前面,进程执行会较快。 如果执行成功则返回 0,否则返回-1,失败原因存于 errno 中。 EPERM 一般用户企图转用负的参数 inc 值改变进程优先顺序。 on_exit(设置程序正常结束前调用的函数) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 _exit,atexit,exit #include int on_exit(void (* function)(int, void*),void *arg); on_exit()用来设置一个程序正常结束前调用的函数。当程序通过 调用 exit()或从 main 中返回时,参数 function 所指定的函数会先 被调用,然后才真正由 exit()结束程序。参数 arg 指针会传给参数 function 函数,详细情况请见范例。 如果执行成功则返回 0,否则返回-1,失败原因存于 errno 中。 范例 #include void my_exit(int status,void *arg) { printf(“before exit()!\n”); printf(“exit (%d)\n”,status); printf(“arg = %s\n”,(char*)arg); } main() { char * str=”test”; on_exit(my_exit,(void *)str); exit(1234); } 执行 before exit()! exit (1234) arg = test setpgid(设置进程组识别码) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 getpgid,setpgrp,getpgrp #include int setpgid(pid_t pid,pid_t pgid); setpgid()将参数 pid 指定进程所属的组识别码设为参数 pgid 指定 的组识别码。如果参数 pid 为 0,则会用来设置目前进程的组识别码, 如果参数 pgid 为 0,则会以目前进程的进程识别码来取代。 执行成功则返回组识别码,如果有错误则返回-1,错误原因存于 errno 中。 EINVAL 参数 pgid 小于 0。 EPERM 进程权限不足,无法完成调用。 ESRCH 找不到符合参数 pid 指定的进程。 setpgrp(设置进程组识别码) 相关函数 表头文件 定义函数 函数说明 返回值 getpgid,setpgid,getpgrp #include int setpgrp(void); setpgrp()将目前进程所属的组识别码设为目前进程的进程识别码。 此函数相当于调用 setpgid(0,0)。 执行成功则返回组识别码,如果有错误则返回-1,错误原因存于 errno 中。 setpriority(设置程序进程执行优先权) 相关函数 表头文件 定义函数 函数说明 返回值 getpriority,nice #include #include int setpriority(int which,int who, int prio); setpriority()可用来设置进程、进程组和用户的进程执行优先权。参 数 which 有三种数值,参数 who 则依 which 值有不同定义: which who 代表的意义 PRIO_PROCESS who 为进程识别码 PRIO_PGRP who 为进程的组识别码 PRIO_USER who 为用户识别码 参数 prio 介于-20 至 20 之间。代表进程执行优先权,数值越低代表 有较高的优先次序,执行会较频繁。此优先权默认是 0,而只有超 级用户(root)允许降低此值。 执行成功则返回 0,如果有错误发生返回值则为-1,错误原因存于 errno。 ESRCH 参数 which 或 who 可能有错,而找不到符合的进程 EINVAL 参数 which 值错误。 EPERM 权限不够,无法完成设置 EACCES 一般用户无法降低优先权 system(执行 shell 命令) 相关函数 表头文件 定义函数 函数说明 返回值 fork,execve,waitpid,popen #include int system(const char * string); system()会调用 fork()产生子进程,由子进程来调用/bin/sh-c string 来执行参数 string 字符串所代表的命令,此命令执行完后随 即返回原调用的进程。在调用 system()期间 SIGCHLD 信号会被 暂时搁置,SIGINT 和 SIGQUIT 信号则会被忽略。 如果 system()在调用/bin/sh 时失败则返回 127,其他失败原因返 回-1。若参数 string 为空指针(NULL),则返回非零值。如果 system()调用成功则最后会返回执行 shell 命令后的返回值,但是 附加说明 此返回值也有可能为 system()调用/bin/sh 失败所返回的 127,因 此最好能再检查 errno 来确认执行成功。 在 编 写 具 有 SUID/SGID 权 限 的 程 序 时 请 勿 使 用 system(),system()会继承环境变量,通过环境变量可能会造 成系统安全的问题。 范例 #include main() { system(“ls -al /etc/passwd /etc/shadow”); } 执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd -r--------- 1 root root 572 Sep 2 15 :34 /etc/shadow wait(等待子进程中断或结束) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 waitpid,fork #include #include pid_t wait (int * status); wait()会暂时停止目前进程的执行,直到有信号来到或子进程结 束。如果在调用 wait()时子进程已经结束,则 wait()会立即返 回子进程结束状态值。子进程的结束状态值会由参数 status 返回, 而子进程的进程识别码也会一快返回。如果不在意结束状态值,则 参 数 status 可 以 设 成 NULL 。 子 进 程 的 结 束 状 态 值 请 参 考 waitpid()。 如果执行成功则返回子进程识别码( PID),如果有错误发生则返 回-1。失败原因存于 errno 中。 范例 #include #include #include #include main() { pid_t pid; int status,i; if(fork()= =0){ printf(“This is the child process .pid =%d\n”,getpid()); exit(5); }else{ sleep(1); printf(“This is the parent process ,wait for child...\n”; pid=wait(&status); i=WEXITSTATUS(status); printf(“child’s pid =%d .exit status=^d\n”,pid,i); } } 执行 This is the child process.pid=1501 This is the parent process .wait for child... child’s pid =1501,exit status =5 waitpid(等待子进程中断或结束) 相关函数 表头文件 定义函数 函数说明 wait,fork #include #include pid_t waitpid(pid_t pid,int * status,int options); waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程 结束。如果在调用 wait()时子进程已经结束,则 wait()会立即 返回子进程结束状态值。子进程的结束状态值会由参数 status 返回, 而子进程的进程识别码也会一快返回。如果不在意结束状态值,则 参数 status 可以设成 NULL。参数 pid 为欲等待的子进程识别码,其 他数值意义如下: 返回值 范例 参考 wait()。 pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。 pid=-1 等待任何子进程,相当于 wait()。 pid=0 等待进程组识别码与目前进程相同的任何子进程。 pid>0 等待任何子进程识别码为 pid 的子进程。 参数 option 可以为 0 或下面的 OR 组合: WNOHANG 如果没有任何已经结束的子进程则马上返回,不予以 等待。 WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束 状态不予以理会。 子进程的结束状态返回后存于 status,底下有几个宏可判别结束情 况: WIFEXITED(status)如果子进程正常结束则为非 0 值。 WEXITSTATUS(status)取得子进程 exit()返回的结束代码,一 般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。 WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为 真 WTERMSIG(status) 取得子进程因信号而中止的信号代码,一般 会先用 WIFSIGNALED 来判断后才使用此宏。 WIFSTOPPED(status) 如果子进程处于暂停执行情况则此宏值为 真。一般只有使用 WUNTRACED 时才会有此情况。 WSTOPSIG(status) 取得引发子进程暂停的信号代码,一般会先 用 WIFSTOPPED 来判断后才使用此宏。 如果执行成功则返回子进程识别码( PID),如果有错误发生则返 回-1。失败原因存于 errno 中。 fprintf(格式化输出数据至文件) 相关函数 表头文件 定义函数 函数说明 printf,fscanf,vfprintf #include int fprintf(FILE * stream, const char * format,.......); fprintf()会根据参数 format 字符串来转换并格式化数据,然后将 结 果 输 出 到 参 数 stream 指 定 的 文 件 中 , 直 到 出 现 字 符 串 结 束 (‘\0‘)为止。 返回值 范例 #include 关于参数 format 字符串的格式请参考 printf()。成功则返回实际输 出的字符数,失败则返回-1,错误原因存于 errno 中。 main() { int i = 150; int j = -100; double k = 3.14159; fprintf(stdout,”%d %f %x \n”,j,k,i); fprintf(stdout,”%2d %*d\n”,i,2,i); } 执行 -100 3.141590 96 150 150 fscanf(格式化字符串输入) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 scanf,sscanf #include int fscanf(FILE * stream ,const char *format,....); fscanf()会自参数 stream 的文件流中读取字符串,再根据参数 format 字符串来转换并格式化数据。 格式转换形式请参考 scanf()。转换后的结构存于对应的参数内。 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。 范例 #include main() { int i; unsigned int j; char s[5]; fscanf(stdin,”%d %x %5[a-z] %*s %f”,&i,&j,s,s); printf(“%d %d %s \n”,i,j,s); } 执行 10 0x1b aaaaaaaaa bbbbbbbbbb /*从键盘输入*/ 10 27 aaaaa printf(格式化输出数据) 相关函数 表头文件 定义函数 函数说明 scanf,snprintf #include int printf(const char * format,.............); printf()会根据参数 format 字符串来转换并格式化数据,然后将 结果写出到标准输出设备,直到出现字符串结束(’\0’)为止。 参数 format 字符串可包含下列三种字符类型: 1.一般文本,伴随直接输出。 2.ASCII 控制字符,如\t、\n 等。 3.格式转换字符。 格式转换为一个百分比符号(%)及其后的格式字符所组成。一般 而言,每个%符号在其后都必需有一 printf()的参数与之相呼应 (只有当%%转换字符出现时会直接输出%字符),而欲输出的数 据类型必须与其相对应的转换字符类型相同。 printf()格式转换的一般形式如下: %〔flags〕〔width〕〔.prec〕type 以中括号括起来的参数为选择性参数,而%与 type 则是必要的。底 下先介绍 type 的几种形式: 整数: %d 整数的参数会被转成一有符号的十进制数字 返回值 %u 整数的参数会被转成一无符号的十进制数字 %o 整数的参数会被转成一无符号的八进制数字 %x 整数的参数会被转成一无符号的十六进制数字,并以小写 abcdef 表示 %X 整数的参数会被转成一无符号的十六进制数字,并以大写 ABCDEF 表示 浮点型数: %f double 型的参数会被转成十进制数字,并取到小数点以下六位, 四舍五入。 %e double 型的参数以指数形式打印,有一个数字会在小数点前, 六位数字在小数点后,而在指数部分会以小写的 e 来表示。 %E 与%e 作用相同,唯一区别是指数部分将以大写的 E 来表示。 %g double 型的参数会自动选择以%f 或%e 的格式来打印,其标准 是根据欲打印的数值及所设置的有效位数来决定。 %G 与%g 作用相同,唯一区别在以指数形态打印时会选择%E 格 式。 字符及字符串: %c 整型数的参数会被转成 unsigned char 型打印出。 %s 指向字符串的参数会被逐字输出,直到出现 NULL 字符为止 %p 如果是参数是“void *”型指针则使用十六进制格式显示。 prec 有几种情况: 1. 正整数的最小位数。 2.在浮点型数中代表小数位数 3.在%g 格式代表有效位数的最大值。 4.在%s 格式代表字符串的最大长度。 5.若为× 符号则代表下个参数值为最大长度。 width 为参数的最小长度,若此栏并非数值,而是*符号,则表示以 下一个参数当做参数长度。 flags 有下列几种情况: - 此旗标会将一数值向左对齐。 + 一般在打印负数时,printf()会加印一个负号,整数则不加任 何负号。此旗标会使得在打印正数前多一个正号(+)。 # 此旗标会根据其后转换字符的不同而有不同含义。当在类型为 o 之前(如%#o),则会在打印八进制数值前多印一个 o。 而在类型为 x 之前(%#x)则会在打印十六进制数前多印 ’0x’,在型态为 e、E、f、g 或 G 之前则会强迫数值打印小 数点。在类型为 g 或 G 之前时则同时保留小数点及小数位 数末尾的零。 0 当有指定参数时,无数字的参数将补上 0。默认是关闭此旗标, 所以一般会打印出空白字符。 成功则返回实际输出的字符数,失败则返回 -1,错误原因存于 errno 中。 范例 #include main() { int i = 150; int j = -100; double k = 3.14159; printf(“%d %f %x\n”,j,k,i); printf(“%2d %*d\n”,i,2,i); /*参数 2 会代入格式*中,而与%2d 同意义*/ } 执行 -100 3.14159 96 150 150 sacnf(格式化字符串输入) 相关函数 表头文件 定义函数 函数说明 fscanf,snprintf #include int scanf(const char * format,.......); scanf()会将输入的数据根据参数 format 字符串来转换并格式化 数据。scanf()格式转换的一般形式如下: %[*][size][l][h]type 以中括号括起来的参数为选择性参数,而%与 type 则是必要的。 * 代表该对应的参数数据忽略不保存。 size 为允许参数输入的数据长度。 l 输入的数据数值以 long int 或 double 型保存。 h 输入的数据数值以 short int 型保存。 底下介绍 type 的几种形式: %d 输入的数据会被转成一有符号的十进制数字(int)。 %i 输入的数据会被转成一有符号的十进制数字,若输入数据以 “0x”或“0X”开头代表转换十六进制数字,若以“0”开头则转换八 进制数字,其他情况代表十进制。 %0 输入的数据会被转换成一无符号的八进制数字。 %u 输入的数据会被转换成一无符号的正整数。 返回值 %x 输入的数据为无符号的十六进制数字,转换后存于 unsigned int 型变量。 %X 同%x %f 输入的数据为有符号的浮点型数,转换后存于 float 型变量。 %e 同%f %E 同%f %g 同%f %s 输入数据为以空格字符为终止的字符串。 %c 输入数据为单一字符。 [] 读取数据但只允许括号内的字符。如[a-z]。 [^] 读取数据但不允许中括号的^符号后的字符出现,如[^0-9]. 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。 范例 #include main() { int i; unsigned int j; char s[5]; scanf(“%d %x %5[a-z] %*s %f”,&i,&j,s,s); printf(“%d %d %s\n”,i,j,s); } 执行 10 0x1b aaaaaaaaaa bbbbbbbbbb 10 27 aaaaa sprintf(格式化字符串复制) 相关函数 表头文件 定义函数 printf,sprintf #include int sprintf( char *str,const char * format,.........); 函数说明 返回值 附加说明 sprintf()会根据参数 format 字符串来转换并格式化数据,然后将 结 果 复 制 到 参 数 str 所 指 的 字 符 串 数 组 , 直 到 出 现 字 符 串 结 束 (’\0’)为止。关于参数 format 字符串的格式请参考 printf()。 成功则返回参数 str 字符串长度,失败则返回-1,错误原因存于 errno 中。 使用此函数得留意堆栈溢出,或改用 snprintf()。 范例 #include main() { char * a=”This is string A!”; char buf[80]; sprintf(buf,”>>> %s<<<\n”,a); printf(“%s”.buf); } 执行 >>>This is string A!<<< sscanf(格式化字符串输入) 相关函数 表头文件 定义函数 函数说明 返回值 scanf,fscanf #include int sscanf (const char *str,const char * format,........); sscanf()会将参数 str 的字符串根据参数 format 字符串来转换并格 式化数据。格式转换形式请参考 scanf()。转换后的结果存于对应 的参数内。 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。 范例 #include main() { int i; unsigned int j; char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”; char s[5]; sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s); printf(“%d %d %s\n”,i,j,s); } 执行 10 27 aaaaa vfprintf(格式化输出数据至文件) 相关函数 printf,fscanf,fprintf 表头文件 #include 定义函数 #include int vfprintf(FILE *stream,const char * format,va_list ap); 函数说明 返回值 vfprintf()会根据参数 format 字符串来转换并格式化数据,然后 将结果输出到参数 stream 指定的文件中,直到出现字符串结束(’ \0’)为止。关于参数 format 字符串的格式请参考 printf()。va_list 用法请参考附录 C 或 vprintf()范例。 成功则返回实际输出的字符数,失败则返回 -1,错误原因存于 errno 中。 范例 参考 fprintf()及 vprintf()。 vfscanf(格式化字符串输入) 相关函数 scanf,sscanf,fscanf 表头文件 定义函数 函数说明 返回值 #include int vfscanf(FILE * stream,const char * format ,va_list ap); vfscanf()会自参数 stream 的文件流中读取字符串,再根据参数 format 字 符 串 来 转 换 并 格 式 化 数 据 。 格 式 转 换 形 式 请 参 考 scanf()。转换后的结果存于对应的参数内。va_list 用法请参考附录 C 或 vprintf()。 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。 范例 参考 fscanf()及 vprintf()。 vprintf(格式化输出数据) 相关函数 表头文件 定义函数 函数说明 返回值 范例 #include printf,vfprintf,vsprintf #include #include int vprintf(const char * format,va_list ap); vprintf()作用和 printf()相同,参数 format 格式也相同。 va_list 为不定个数的参数列,用法及范例请参考附录 C。 成功则返回实际输出的字符数,失败则返回 -1,错误原因存于 errno 中。 #include int my_printf( const char *format,……) { va_list ap; int retval; va_start(ap,format); printf(“my_printf( ):”); retval = vprintf(format,ap); va_end(ap); return retval; } main() { int i = 150,j = -100; double k = 3.14159; my_printf(“%d %f %x\n”,j,k,i); my_printf(“%2d %*d\n”,i,2,i); } 执行 my_printf() : -100 3.14159 96 my_printf() : 150 150 vscanf(格式化字符串输入) 相关函数 表头文件 定义函数 函数说明 返回值 vsscanf,vfscanf #include #include int vscanf( const char * format,va_list ap); vscanf()会将输入的数据根据参数 format 字符串来转换并格式化 数据。格式转换形式请参考 scanf()。转换后的结果存于对应的参 数内。va_list 用法请参考附录 C 或 vprintf()范例。 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。 范例 请参考 scanf()及 vprintf()。 vsprintf(格式化字符串复制) 相关函数 表头文件 vnsprintf,vprintf,snprintf #include 定义函数 int vsprintf( char * str,const char * format,va_list ap); 函数说明 返回值 vsprintf()会根据参数 format 字符串来转换并格式化数据,然后 将结果复制到参数 str 所指的字符串数组,直到出现字符串结束 ( ’ \0’ ) 为 止 。 关 于 参 数 format 字 符 串 的 格 式 请 参 考 printf()。va_list 用法请参考附录 C 或 vprintf()范例。 成功则返回参数 str 字符串长度,失败则返回-1,错误原因存于 errno 中。 范例 请参考 vprintf()及 vsprintf()。 vsscanf(格式化字符串输入) 相关函数 表头文件 定义函数 函数说明 返回值 vscanf,vfscanf #include int vsscanf(const char * str,const char * format,va_list ap); vsscanf()会将参数 str 的字符串根据参数 format 字符串来转换并 格式化数据。格式转换形式请参考附录 C 或 vprintf()范例。 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。 范例 请参考 sscanf()及 vprintf()。 access(判断是否具有存取文件的权限) 相关函数 表头文件 stat,open,chmod,chown,setuid,setgid #include 定义函数 int access(const char * pathname,int mode); 函数说明 返回值 错误代码 附加说明 access()会检查是否可以读/写某一已存在的文件。参数 mode 有几 种情况组合,R_OK,W_OK,X_OK 和 F_OK。R_OK,W_OK 与 X_OK 用来检查文件是否具有读取、写入和执行的权限。F_OK 则是 用来判断该文件是否存在。由于 access()只作权限的核查,并不 理会文件形态或文件内容,因此,如果一目录表示为“可写入”, 表示可以在该目录中建立新文件等操作,而非意味此目录可以被当 做文件处理。例如,你会发现 DOS 的文件都具有“可执行”权限, 但用 execve()执行时则会失败。 若所有欲查核的权限都通过了检查则返回 0 值,表示成功,只要有 一权限被禁止则返回-1。 EACCESS 参数 pathname 所指定的文件不符合所要求测试的权限。 EROFS 欲测试写入权限的文件存在于只读文件系统内。 EFAULT 参数 pathname 指针超出可存取内存空间。 EINVAL 参数 mode 不正确。 ENAMETOOLONG 参数 pathname 太长。 ENOTDIR 参数 pathname 为一目录。 ENOMEM 核心内存不足 ELOOP 参数 pathname 有过多符号连接问题。 EIO I/O 存取错误。 使 用 access ( ) 作 用 户 认 证 方 面 的 判 断 要 特 别 小 心 , 例 如 在 access()后再做 open()的空文件可能会造成系统安全上的问题。 范例 /* 判断是否允许读取/etc/passwd */ #include int main() { if (access(“/etc/passwd”,R_OK) = =0) printf(“/etc/passwd can be read\n”); } 执行 /etc/passwd can be read alphasort(依字母顺序排序目录结构) 相关函数 scandir,qsort 表头文件 定义函数 函数说明 返回值 #include int alphasort(const struct dirent **a,const struct dirent **b); alphasort ( ) 为 scandir ( ) 最 后 调 用 qsort ( ) 函 数 时 传 给 qsort ( ) 作 为 判 断 的 函 数 , 详 细 说 明 请 参 考 scandir ( ) 及 qsort()。 参考 qsort()。 范例 /* 读取/目录下所有的目录结构,并依字母顺序排列 */ main() { struct dirent **namelist; int i,total; total = scandir(“/”,&namelist ,0,alphasort); if(total <0) perror(“scandir”); else{ for(i=0;id_name); printf(“total = %d\n”,total); } } 执行 .. .gnome .gnome_private ErrorLog Weblog bin boot dev dosc dosd etc home lib lost+found misc mnt opt proc root sbin tmp usr var total = 24 chdir(改变当前的工作目录) 相关函数 表头文件 定义函数 函数说明 返回值 getcwd,chroot #include int chdir(const char * path); chdir()用来将当前的工作目录改变成以参数 path 所指的目录。 执行成功则返回 0,失败返回-1,errno 为错误代码。 范例 #include main() { chdir(“/tmp”); printf(“current working directory: %s\n”,getcwd(NULL,NULL)); } 执行 current working directory :/tmp chmod(改变文件的权限) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 fchmod,stat,open,chown #include #include int chmod(const char * path,mode_t mode); chmod()会依参数 mode 权限来更改参数 path 指定文件的权限。参 数 mode 有下列数种组合: S_ISUID 04000 文件的(set user-id on execution)位 S_ISGID 02000 文件的(set group-id on execution)位 S_ISVTX 01000 文件的 sticky 位 S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限 S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限 S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限 S_IRGRP 00040 用户组具可读取权限 S_IWGRP 00020 用户组具可写入权限 S_IXGRP 00010 用户组具可执行权限 S_IROTH 00004 其他用户具可读取权限 S_IWOTH 00002 其他用户具可写入权限 S_IXOTH 00001 其他用户具可执行权限 只有该文件的所有者或有效用户识别码为 0,才可以修改该文件权 限。基于系统安全,如果欲将数据写入一执行文件,而该执行文件 具有 S_ISUID 或 S_ISGID 权限,则这两个位会被清除。如果一目录 具有 S_ISUID 位权限,表示在此目录下只有该文件的所有者或 root 可以删除该文件。 权限改变成功返回 0,失败返回-1,错误原因存于 errno。 EPERM 进程的有效用户识别码与欲修改权限的文件拥有者不同, 而且也不具 root 权限。 EACCESS 参数 path 所指定的文件无法存取。 EROFS 欲写入权限的文件存在于只读文件系统内。 EFAULT 参数 path 指针超出可存取内存空间。 EINVAL 参数 mode 不正确 ENAMETOOLONG 参数 path 太长 ENOENT 指定的文件不存在 ENOTDIR 参数 path 路径并非一目录 ENOMEM 核心内存不足 ELOOP 参数 path 有过多符号连接问题。 EIO I/O 存取错误 范例 /* 将/etc/passwd 文件权限设成 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH */ #include #include main() { chmod(“/etc/passwd”,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); } chown(改变文件的所有者) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 fchown,lchown,chmod #include #include int chown(const char * path, uid_t owner,gid_t group); chown()会将参数 path 指定文件的所有者变更为参数 owner 代表 的用户,而将该文件的组变更为参数 group 组。如果参数 owner 或 group 为-1,对应的所有者或组不会有所改变。root 与文件所有者皆 可改变文件组,但所有者必须是参数 group 组的成员。当 root 用 chown ( ) 改 变 文 件 所 有 者 或 组 时 , 该 文 件 若 具 有 S_ISUID 或 S_ISGID 权限,则会清除此权限位,此外如果具有 S_ISGID 权限但 不具 S_IXGRP 位,则该文件会被强制锁定,文件模式会保留。 成功则返回 0,失败返回-1,错误原因存于 errno。 参考 chmod()。 范例 /* 将/etc/passwd 的所有者和组都设为 root */ #include #include main() { chown(“/etc/passwd”,0,0); } chroot(改变根目录) 相关函数 chdir 表头文件 #include 定义函数 int chroot(const char * path); 函数说明 返回值 chroot()用来改变根目录为参数 path 所指定的目录。只有超级用 户才允许改变根目录,子进程将继承新的根目录。 调用成功则返回 0,失败则返-1,错误代码存于 errno。 错误代码 EPERM 权限不足,无法改变根目录。 EFAULT 参数 path 指针超出可存取内存空间。 ENAMETOOLONG 参数 path 太长。 ENOTDIR 路径中的目录存在但却非真正的目录。 EACCESS 存取目录时被拒绝 ENOMEM 核心内存不足。 ELOOP 参数 path 有过多符号连接问题。 EIO I/O 存取错误。 范例 /* 将根目录改为/tmp ,并将工作目录切换至/tmp */ #include main() { chroot(“/tmp”); chdir(“/”); } closedir(关闭目录) 相关函数 表头文件 定义函数 opendir #include #include int closedir(DIR *dir); 函数说明 返回值 错误代码 closedir()关闭参数 dir 所指的目录流。 关闭成功则返回 0,失败返回-1,错误原因存于 errno 中。 EBADF 参数 dir 为无效的目录流 范例 参考 readir()。 fchdir(改变当前的工作目录) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 getcwd,chroot #include int fchdir(int fd); fchdir()用来将当前的工作目录改变成以参数 fd 所指的文件描述 词。 执行成功则返回 0,失败返回-1,errno 为错误代码。 范例 #include #include #include #include main() { int fd; fd = open(“/tmp”,O_RDONLY); fchdir(fd); printf(“current working directory : %s \n”,getcwd(NULL,NULL)); close(fd); } 执行 current working directory : /tmp fchmod(改变文件的权限) 相关函数 表头文件 chmod,stat,open,chown #include 定义函数 #include int fchmod(int fildes,mode_t mode); 函数说明 返回值 fchmod()会依参数 mode 权限来更改参数 fildes 所指文件的权限。 参数 fildes 为已打开文件的文件描述词。 参数 mode 请参考 chmod()。 权限改变成功则返回 0,失败返回-1,错误原因存于 errno。 错误原因 EBADF 参数 fildes 为无效的文件描述词。 EPERM 进程的有效用户识别码与欲修改权限的文件所有者不同, 而且也不具 root 权限。 EROFS 欲写入权限的文件存在于只读文件系统内。 EIO I/O 存取错误。 范例 #include #include main() { int fd; fd = open (“/etc/passwd”,O_RDONLY); fchmod(fd,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); close(fd); } fchown(改变文件的所有者) 相关函数 表头文件 定义函数 chown,lchown,chmod #include #include int fchown(int fd,uid_t owner,gid_t group); 函数说明 返回值 fchown()会将参数 fd 指定文件的所有者变更为参数 owner 代表 的用户,而将该文件的组变更为参数 group 组。如果参数 owner 或 group 为-1,对映的所有者或组有所改变。参数 fd 为已打开的文件描 述词。当 root 用 fchown()改变文件所有者或组时,该文件若具 S_ISUID 或 S_ISGID 权限,则会清除此权限位。 成功则返回 0,失败则返回-1,错误原因存于 errno。 错误代码 EBADF 参数 fd 文件描述词为无效的或该文件已关闭。 EPERM 进程的有效用户识别码与欲修改权限的文件所有者不同, 而且也不具 root 权限,或是参数 owner、group 不正确。 EROFS 欲写入的文件存在于只读文件系统内。 ENOENT 指定的文件不存在 EIO I/O 存取错误 范例 #include #include #include main() { int fd; fd = open (“/etc/passwd”,O_RDONLY); chown(fd,0,0); close(fd); } fstat(由文件描述词取得文件状态) 相关函数 表头文件 定义函数 stat,lstat,chmod,chown,readlink,utime #include #include int fstat(int fildes,struct stat *buf); 函数说明 返回值 fstat()用来将参数 fildes 所指的文件状态,复制到参数 buf 所指的 结构中(struct stat)。fstat()与 stat()作用完全相同,不同处在 于传入的参数为已打开的文件描述词。详细内容请参考 stat()。 执行成功则返回 0,失败返回-1,错误代码存于 errno。 范例 #include #include #include main() { struct stat buf; int fd; fd = open (“/etc/passwd”,O_RDONLY); fstat(fd,&buf); printf(“/etc/passwd file size +%d\n “,buf.st_size); } 执行 /etc/passwd file size = 705 ftruncate(改变文件大小) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 open,truncate #include int ftruncate(int fd,off_t length); ftruncate()会将参数 fd 指定的文件大小改为参数 length 指定的大 小。参数 fd 为已打开的文件描述词,而且必须是以写入模式打开的 文件。如果原来的文件大小比参数 length 大,则超过的部分会被删 去。 执行成功则返回 0,失败返回-1,错误原因存于 errno。 EBADF 参数 fd 文件描述词为无效的或该文件已关闭。 EINVAL 参数 fd 为一 socket 并非文件,或是该文件并非以写入模式 打开。 getcwd(取得当前的工作目录) 相关函数 get_current_dir_name,getwd,chdir 表头文件 #include 定义函数 char * getcwd(char * buf,size_t size); 函数说明 返回值 getcwd()会将当前的工作目录绝对路径复制到参数 buf 所指的内 存空间,参数 size 为 buf 的空间大小。在调用此函数时,buf 所指的 内存空间要足够大,若工作目录绝对路径的字符串长度超过参数 size 大小,则回值 NULL,errno 的值则为 ERANGE。倘若参数 buf 为 NULL,getcwd()会依参数 size 的大小自动配置内存(使用 malloc()),如果参数 size 也为 0,则 getcwd()会依工作目录 绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用 完此字符串后利用 free()来释放此空间。 执行成功则将结果复制到参数 buf 所指的内存空间,或是返回自动 配置的字符串指针。失败返回 NULL,错误代码存于 errno。 范例 #include main() { char buf[80]; getcwd(buf,sizeof(buf)); printf(“current working directory : %s\n”,buf); } 执行 current working directory :/tmp link(建立文件连接) 相关函数 表头文件 定义函数 symlink,unlink #include int link (const char * oldpath,const char * newpath); 函数说明 返回值 link()以参数 newpath 指定的名称来建立一个新的连接(硬连接) 到参数 oldpath 所指定的已存在文件。如果参数 newpath 指定的名称 为一已存在的文件则不会建立连接。 成功则返回 0,失败返回-1,错误原因存于 errno。 附加说明 错误代码 link()所建立的硬连接无法跨越不同文件系统,如果需要请改用 symlink()。 EXDEV 参数 oldpath 与 newpath 不是建立在同一文件系统。 EPERM 参数 oldpath 与 newpath 所指的文件系统不支持硬连接 EROFS 文件存在于只读文件系统内 EFAULT 参数 oldpath 或 newpath 指针超出可存取内存空间。 ENAMETOLLONG 参数 oldpath 或 newpath 太长 ENOMEM 核心内存不足 EEXIST 参数 newpath 所指的文件名已存在。 EMLINK 参数 oldpath 所指的文件已达最大连接数目。 ELOOP 参数 pathname 有过多符号连接问题 ENOSPC 文件系统的剩余空间不足。 EIO I/O 存取错误。 范例 /* 建立/etc/passwd 的硬连接为 pass */ #include main() { link(“/etc/passwd”,”pass”); } lstat(由文件描述词取得文件状态) 相关函数 表头文件 定义函数 函数说明 stat,fstat,chmod,chown,readlink,utime #include #include int lstat (const char * file_name.struct stat * buf); lstat()与 stat()作用完全相同,都是取得参数 file_name 所指的 文件状态,其差别在于,当文件为符号连接时,lstat()会返回该 link 本身的状态。 详细内容请参考 stat()。 返回值 执行成功则返回 0,失败返回-1,错误代码存于 errno。 范例 参考 stat()。 opendir(打开目录) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 open,readdir,closedir,rewinddir,seekdir,telldir,scandir #include #include DIR * opendir(const char * name); opendir()用来打开参数 name 指定的目录,并返回 DIR* 形态的 目录流,和 open()类似,接下来对目录的读取和搜索都要使用 此返回值 成功则返回 DIR* 型态的目录流,打开失败则返回 NULL EACCESS 权限不足 EMFILE 已达到进程可同时打开的文件数上限。 ENFILE 已达到系统可同时打开的文件数上限。 ENOTDIR 参数 name 非真正的目录 ENOENT 参数 name 指定的目录不存在,或是参数 name 为一空字 符串。 ENOMEM 核心内存不足。 readdir(读取目录) 相关函数 表头文件 定义函数 open,opendir,closedir,rewinddir,seekdir,telldir,scandir #include #include struct dirent * readdir(DIR * dir); 函数说明 返回值 附加说明 readdir()返回参数 dir 目录流的下个目录进入点。结构 dirent 定义 如下: struct dirent { ino_t d_ino; ff_t d_off; signed short int d_reclen; unsigned char d_type; har d_name[256; }; d_ino 此目录进入点的 inode d_off 目录文件开头至此目录进入点的位移 d_reclen _name 的长度,不包含 NULL 字符 d_type d_name 所指的文件类型 d_name 文件名 成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返 回 NULL。 EBADF 参数 dir 为无效的目录流。 范例 #include #include #include main() { DIR * dir; struct dirent * ptr; int i; dir =opendir(“/etc/rc.d”); while((ptr = readdir(dir))!=NULL) { printf(“d_name: %s\n”,ptr->d_name); } closedir(dir); } 执行 d_name:. d_name:.. d_name:init.d d_name:rc0.d d_name:rc1.d d_name:rc2.d d_name:rc3.d d_name:rc4.d d_name:rc5.d d_name:rc6.d d_name:rc d_name:rc.local d_name:rc.sysinit readlink(取得符号连接所指的文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 stat,lstat,symlink #include int readlink(const char * path ,char * buf,size_t bufsiz); readlink()会将参数 path 的符号连接内容存到参数 buf 所指的内 存空间,返回的内容不是以 NULL 作字符串结尾,但会将字符串的 字符数返回。若参数 bufsiz 小于符号连接的内容长度,过长的内容 会被截断。 执行成功则传符号连接所指的文件路径字符串,失败则返回-1,错 误代码存于 errno。 EACCESS 取文件时被拒绝,权限不够 EINVAL 参数 bufsiz 为负数 EIO I/O 存取错误。 ELOOP 欲打开的文件有过多符号连接问题。 ENAMETOOLONG 参数 path 的路径名称太长 ENOENT 参数 path 所指定的文件不存在 ENOMEM 核心内存不足 ENOTDIR 参数 path 路径中的目录存在但却非真正的目录。 remove(删除文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 link,rename,unlink #include int remove(const char * pathname); remove()会删除参数 pathname 指定的文件。如果参数 pathname 为 一文件,则调用 unlink()处理,若参数 pathname 为一目录,则调 用 rmdir()来处理。请参考 unlink()与 rmdir()。 成功则返回 0,失败则返回-1,错误原因存于 errno EROFS 欲写入的文件存在于只读文件系统内 EFAULT 参数 pathname 指针超出可存取内存空间。 ENAMETOOLONG 参数 pathname 太长 ENOMEM 核心内存不足 ELOOP 参数 pathname 有过多符号连接问题 EIO I/O 存取错误。 rename(更改文件名称或位置) 相关函数 表头文件 定义函数 函数说明 返回值 link,unlink,symlink #include int rename(const char * oldpath,const char * newpath); rename()会将参数 oldpath 所指定的文件名称改为参数 newpath 所指的文件名称。若 newpath 所指定的文件已存在,则会被删除。 执行成功则返回 0,失败返回-1,错误原因存于 errno 范例 /* 设计一个 DOS 下的 rename 指令:rename 旧文件名 新文件名*/ #include void main(int argc,char **argv) { if(argc<3){ printf(“Usage: %s old_name new_name\n”,argv[0]); return; } printf(“%s=>%s”,argc[1],argv[2]); if(rename(argv[1],argv[2]<0) printf(“error!\n”); else printf(“ok!\n”); } rewinddir(重设读取目录的位置为开头位置) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 open,opendir,closedir,telldir,seekdir,readdir,scandir #include #include void rewinddir(DIR *dir); rewinddir()用来设置参数 dir 目录流目前的读取位置为原来开头 的读取位置。 无 EBADF dir 为无效的目录流 范例 #include #include #include main() { DIR * dir; struct dirent *ptr; dir = opendir(“/etc/rc.d”); while((ptr = readdir(dir))!=NULL) { printf(“d_name :%s\n”,ptr->d_name); } rewinddir(dir); printf(“readdir again!\n”); while((ptr = readdir(dir))!=NULL) { printf(“d_name: %s\n”,ptr->d_name); } closedir(dir); } 执行 d_name:. d_name:.. d_name:init.d d_name:rc0.d d_name:rc1.d d_name:rc2.d d_name:rc3.d d_name:rc4.d d_name:rc5.d d_name:rc6.d d_name:rc d_name:rc.local d_name:rc.sysinit readdir again! d_name:. d_name:.. d_name:init.d d_name:rc0.d d_name:rc1.d d_name:rc2.d d_name:rc3.d d_name:rc4.d d_name:rc5.d d_name:rc6.d d_name:rc d_name:rc.local d_name:rc.sysinit seekdir(设置下回读取目录的位置) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 open,opendir,closedir,rewinddir,telldir,readdir,scandir #include void seekdir(DIR * dir,off_t offset); seekdir ( ) 用 来 设 置 参 数 dir 目 录 流 目 前 的 读 取 位 置 , 在 调 用 readdir()时便从此新位置开始读取。参数 offset 代表距离目录文件 开头的偏移量。 无 EBADF 参数 dir 为无效的目录流 范例 #include #include #include main() { DIR * dir; struct dirent * ptr; int offset,offset_5,i=0; dir=opendir(“/etc/rc.d”); while((ptr = readdir(dir))!=NULL) { offset = telldir(dir); if(++i = =5) offset_5 =offset; printf(“d_name :%s offset :%d \n”,ptr->d_name,offset); } seekdir(dir offset_5); printf(“Readdir again!\n”); while((ptr = readdir(dir))!=NULL) { offset = telldir(dir); printf(“d_name :%s offset :%d\n”,ptr->d_name.offset); } closedir(dir); } 执行 d_name : . offset :12 d_name : .. offset:24 d_name : init.d offset 40 d_name : rc0.d offset :56 d_name :rc1.d offset :72 d_name:rc2.d offset :88 d_name:rc3.d offset 104 d_name:rc4.d offset:120 d_name:rc5.d offset:136 d_name:rc6.d offset:152 d_name:rc offset 164 d_name:rc.local offset :180 d_name:rc.sysinit offset :4096 readdir again! d_name:rc2.d offset :88 d_name:rc3.d offset 104 d_name:rc4.d offset:120 d_name:rc5.d offset:136 d_name:rc6.d offset:152 d_name:rc offset 164 d_name:rc.local offset :180 d_name:rc.sysinit offset :4096 stat(取得文件状态) 相关函数 表头文件 定义函数 函数说明 fstat,lstat,chmod,chown,readlink,utime #include #include int stat(const char * file_name,struct stat *buf); stat()用来将参数 file_name 所指的文件状态,复制到参数 buf 所 指的结构中。下面是 struct stat 内各参数的说明: struct stat { dev_t st_dev; /*device*/ ino_t st_ino; /*inode*/ mode_t st_mode; /*protection*/ nlink_t st_nlink; /*number of hard links */ uid_t st_uid; /*user ID of owner*/ gid_t st_gid; /*group ID of owner*/ dev_t st_rdev; /*device type */ off_t st_size; /*total size, in bytes*/ unsigned long st_blksize; /*blocksize for filesystem I/O */ unsigned long st_blocks; /*number of blocks allocated*/ time_t st_atime; /* time of lastaccess*/ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last change */ }; st_dev 文件的设备编号 st_ino 文件的 i-node st_mode 文件的类型和存取的权限 st_nlink 连到该文件的硬连接数目,刚建立的文件值为 1。 st_uid 文件所有者的用户识别码 st_gid 文件所有者的组识别码 st_rdev 若此文件为装置设备文件,则为其设备编号 st_size 文件大小,以字节计算 st_blksize 文件系统的 I/O 缓冲区大小。 st_blcoks 占用文件区块的个数,每一区块大小为 512 个字节。 st_atime 文件最近一次被存取或被执行的时间,一般只有在用 mknod、utime、read、write 与 tructate 时改变。 st_mtime 文件最后一次被修改的时间,一般只有在用 mknod、utime 和 write 时才会改变 st_ctime i-node 最近一次被更改的时间,此参数会在文件所有者、 组、权限被更改时更新 先前所描述的 st_mode 则定义了下列数种情况: S_IFMT 0170000 文件类型的位遮罩 S_IFSOCK 0140000 scoket S_IFLNK 0120000 符号连接 S_IFREG 0100000 一般文件 S_IFBLK 0060000 区块装置 S_IFDIR 0040000 目录 S_IFCHR 0020000 字符装置 S_IFIFO 0010000 先进先出 S_ISUID 04000 文件的(set user-id on execution)位 S_ISGID 02000 文件的(set group-id on execution)位 S_ISVTX 01000 文件的 sticky 位 S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限 S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限 S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限 S_IRGRP 00040 用户组具可读取权限 返回值 S_IWGRP 00020 用户组具可写入权限 S_IXGRP 00010 用户组具可执行权限 S_IROTH 00004 其他用户具可读取权限 S_IWOTH 00002 其他用户具可写入权限 S_IXOTH 00001 其他用户具可执行权限 上述的文件类型在 POSIX 中定义了检查这些类型的宏定义: S_ISLNK (st_mode) 判断是否为符号连接 S_ISREG (st_mode) 是否为一般文件 S_ISDIR (st_mode)是否为目录 S_ISCHR (st_mode)是否为字符装置文件 S_ISBLK (s3e) 是否为先进先出 S_ISSOCK (st_mode) 是否为 socket 若一目录具有 sticky 位(S_ISVTX),则表示在此目录下的文件只 能被该文件所有者、此目录所有者或 root 来删除或改名。 执行成功则返回 0,失败返回-1,错误代码存于 errno 错误代码 ENOENT 参数 file_name 指定的文件不存在 ENOTDIR 路径中的目录存在但却非真正的目录 ELOOP 欲打开的文件有过多符号连接问题,上限为 16 符号连接 EFAULT 参数 buf 为无效指针,指向无法存在的内存空间 EACCESS 存取文件时被拒绝 ENOMEM 核心内存不足 ENAMETOOLONG 参数 file_name 的路径名称太长 范例 #include #include mian() { struct stat buf; stat (“/etc/passwd”,&buf); printf(“/etc/passwd file size = %d \n”,buf.st_size); } 执行 /etc/passwd file size = 705 symlink(建立文件符号连接) 相关函数 表头文件 定义函数 link,unlink #include int symlink( const char * oldpath,const char * newpath); 函数说明 返回值 symlink()以参数 newpath 指定的名称来建立一个新的连接(符号 连接)到参数 oldpath 所指定的已存在文件。参数 oldpath 指定的文 件不一定要存在,如果参数 newpath 指定的名称为一已存在的文件 则不会建立连接。 成功则返回 0,失败返回-1,错误原因存于 errno 错误代码 EPERM 参数 oldpath 与 newpath 所指的文件系统不支持符号连接 EROFS 欲测试写入权限的文件存在于只读文件系统内 EFAULT 参数 oldpath 或 newpath 指针超出可存取内存空间。 ENAMETOOLONG 参数 oldpath 或 newpath 太长 ENOMEM 核心内存不足 EEXIST 参数 newpath 所指的文件名已存在。 EMLINK 参数 oldpath 所指的文件已达到最大连接数目 ELOOP 参数 pathname 有过多符号连接问题 ENOSPC 文件系统的剩余空间不足 EIO I/O 存取错误 范例 #include main() { symlink(“/etc/passwd”,”pass”); } telldir(取得目录流的读取位置) 相关函数 表头文件 open,opendir,closedir,rewinddir,seekdir,readdir,scandir #include 定义函数 函数说明 返回值 错误代码 off_t telldir(DIR *dir); telldir()返回参数 dir 目录流目前的读取位置。此返回值代表距离 目录文件开头的偏移量 返回下个读取位置,有错误发生时返回-1。 EBADF 参数 dir 为无效的目录流。 范例 #include #include #include main() { DIR *dir; struct dirent *ptr; int offset; dir = opendir(“/etc/rc.d”); while((ptr = readdir(dir))!=NULL) { offset = telldir (dir); printf(“d_name : %s offset :%d\n”, ptr->d_name,offset); } closedir(dir); } 执行 d_name : . offset :12 d_name : .. offset:24 d_name : init.d offset 40 d_name : rc0.d offset :56 d_name :rc1.d offset :72 d_name:rc2.d offset :88 d_name:rc3.d offset 104 d_name:rc4.d offset:120 d_name:rc5.d offset:136 d_name:rc6.d offset:152 d_name:rc offset 164 d_name:rc.local offset :180 d_name:rc.sysinit offset :4096 truncate(改变文件大小) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 open,ftruncate #include int truncate(const char * path,off_t length); truncate()会将参数 path 指定的文件大小改为参数 length 指定的 大小。如果原来的文件大小比参数 length 大,则超过的部分会被删 去。 执行成功则返回 0,失败返回-1,错误原因存于 errno。 EACCESS 参数 path 所指定的文件无法存取。 EROFS 欲写入的文件存在于只读文件系统内 EFAULT 参数 path 指针超出可存取内存空间 EINVAL 参数 path 包含不合法字符 ENAMETOOLONG 参数 path 太长 ENOTDIR 参数 path 路径并非一目录 EISDIR 参数 path 指向一目录 ETXTBUSY 参数 path 所指的文件为共享程序,而且正被执行中 ELOOP 参数 path’有过多符号连接问题 EIO I/O 存取错误。 umask(设置建立新文件时的权限遮罩) 相关函数 表头文件 定义函数 函数说明 返回值 creat,open #include #include mode_t umask(mode_t mask); umask()会将系统 umask 值设成参数 mask&0777 后的值,然后将 先前的 umask 值返回。在使用 open()建立新文件时,该参数 mode 并非真正建立文件的权限,而是(mode&~umask)的权限值。例如, 在建立文件时指定文件权限为 0666,通常 umask 值默认为 022,则 该文件的真正权限则为 0666&~022=0644,也就是 rw-r--r-此调用不会有错误值返回。返回值为原先系统的 umask 值。 unlink(删除文件) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 link,rename,remove #include int unlink(const char * pathname); unlink()会删除参数 pathname 指定的文件。如果该文件名为最后 连接点,但有其他进程打开了此文件,则在所有关于此文件的文件 描述词皆关闭后才会删除。如果参数 pathname 为一符号连接,则此 连接会被删除。 成功则返回 0,失败返回-1,错误原因存于 errno EROFS 文件存在于只读文件系统内。 EFAULT 参数 pathname 指针超出可存取内存空间 ENAMETOOLONG 参数 pathname 太长 ENOMEM 核心内存不足 ELOOP 参数 pathname 有过多符号连接问题 EIO I/O 存取错误 utime(修改文件的存取时间和更改时间) 相关函数 表头文件 定义函数 函数说明 utimes,stat #include #include int utime(const char * filename,struct utimbuf * buf); utime()用来修改参数 filename 文件所属的 inode 存取时间。结构 utimbuf 定义如下: struct utimbuf{ time_t actime; time_t modtime; }; 如果参数 buf 为空指针(NULL),则该文件的存取时间和更改时 返回值 错误代码 间全部会设为目前时间。 执行成功则返回 0,失败返回-1,错误代码存于 errno。 EACCESS 存取文件时被拒绝,权限不足 ENOENT 指定的文件不存在。 utimes(修改文件的存取时间和更改时间) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 utime,stat #include #include int utimes(char * filename.struct timeval *tvp); utimes()用来修改参数 filename 文件所属的 inode 存取时间和修 改时间,结构 timeval 定义如下: struct timeval { long tv_sec; long tv_usec; /* 微妙*/ }; 参数 tvp 指向两个 timeval 结构空间,和 utime()使用的 utimebuf 结 构 比 较 , tvp[0].tc_sec 则 为 utimbuf.actime , tvp]1].tv_sec 为 utimbuf.modtime。 执行成功则返回 0。失败返回-1,错误代码存于 errno。 EACCESS 存取文件时被拒绝,权限不足 ENOENT 指定的文件不存在 alarm(设置信号传送闹钟) 相关函数 表头文件 定义函数 signal,sleep #include unsigned int alarm(unsigned int seconds); 函数说明 返回值 alarm()用来设置信号 SIGALRM 在经过参数 seconds 指定的秒数 后传送给目前的进程。如果参数 seconds 为 0,则之前设置的闹钟会 被取消,并将剩下的时间返回。 返回之前闹钟的剩余秒数,如果之前未设闹钟则返回 0。 范例 #include #include void handler() { printf(“hello\n”); } main() { int i; signal(SIGALRM,handler); alarm(5); for(i=1;i<7;i++){ printf(“sleep %d ...\n”,i); sleep(1); } } 执行 sleep 1 ... sleep 2 ... sleep 3 ... sleep 4 ... sleep 5 ... hello sleep 6 ... kill(传送信号给指定的进程) 相关函数 表头文件 定义函数 raise,signal #include #include int kill(pid_t pid,int sig); 函数说明 返回值 kill()可以用来送参数 sig 指定的信号给参数 pid 指定的进程。参数 pid 有几种情况: pid>0 将信号传给进程识别码为 pid 的进程。 pid=0 将信号传给和目前进程相同进程组的所有进程 pid=-1 将信号广播传送给系统内所有的进程 pid<0 将信号传给进程组识别码为 pid 绝对值的所有进程 参数 sig 代表的信号编号可参考附录 D 执行成功则返回 0,如果有错误则返回-1。 错误代码 EINVAL 参数 sig 不合法 ESRCH 参数 pid 所指定的进程或进程组不存在 EPERM 权限不够无法传送信号给指定进程 范例 #include #include #include #include main() { pid_t pid; int status; if(!(pid= fork())){ printf(“Hi I am child process!\n”); sleep(10); return; } else{ printf(“send signal to child process (%d) \n”,pid); sleep(1); kill(pid ,SIGABRT); wait(&status); if(WIFSIGNALED(status)) printf(“chile process receive signal %d\n”,WTERMSIG(status)); } } 执行 sen signal to child process(3170) Hi I am child process! child process receive signal 6 pause(让进程暂停直到信号出现) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 kill,signal,sleep #include int pause(void); pause ( ) 会 令 目 前 的 进 程 暂 停 ( 进 入 睡 眠 状 态 ) , 直 到 被 信 号 (signal)所中断。 只返回-1。 EINTR 有信号到达中断了此函数。 sigaction(查询或设置信号处理方式) 相关函数 表头文件 定义函数 函数说明 signal,sigprocmask,sigpending,sigsuspend #include int sigaction(int signum,const struct sigaction *act ,struct sigaction * oldact); sigaction()会依参数 signum 指定的信号编号来设置该信号的处理 函数。参数 signum 可以指定 SIGKILL 和 SIGSTOP 以外的所有信号。 如果参数结构 sigaction 定义如下: struct sigaction { void (*sa_handler) (int); sigset_t sa_mask; int sa_flags; void (*sa_restorer) (void); } sa_handler 此参数和 signal()的参数 handler 相同,代表新的信号 处理函数,其他意义请参考 signal()。 sa_mask 用来设置在处理该信号时暂时将 sa_mask 指定的信号搁置。 sa_restorer 此参数没有使用 sa_flags 用来设置信号处理的其他相关操作,下列的数值可用 OR 运算(|)组合: 返回值 A_NOCLDSTOP :如果参数 signum 为 SIGCHLD,则当子 进程暂停时并不会通知父进程 SA_ONESHOT/SA_RESETHAND:当调用新的信号处理函 数前,将此信号处理方式改为系统预设的方式。 SA_RESTART:被信号中断的系统调用会自行重启 SA_NOMASK/SA_NODEFER:在处理此信号未结束前不理 会此信号的再次到来。 如果参数 oldact 不是 NULL 指针,则原来的信号处理方式会由此结 构 sigaction 返回。 执行成功则返回 0,如果有错误则返回-1。 错误代码 EINVAL 参 数 signum 不 合 法 , 或 是 企 图 拦 截 SIGKILL/SIGSTOPSIGKILL 信号 EFAULT 参数 act,oldact 指针地址无法存取。 EINTR 此调用被中断 范例 #include #include void show_handler(struct sigaction * act) { switch (act->sa_flags) { case SIG_DFL:printf(“Default action\n”);break; case SIG_IGN:printf(“Ignore the signal\n”);break; default: printf(“0x%x\n”,act->sa_handler); } } main() { int i; struct sigaction act,oldact; act.sa_handler = show_handler; act.sa_flags = SA_ONESHOT|SA_NOMASK; sigaction(SIGUSR1,&act,&oldact); for(i=5;i<15;i++) { printf(“sa_handler of signal %2d =”.i); sigaction(i,NULL,&oldact); } } 执行 sa_handler of signal 5 = Default action sa_handler of signal 6= Default action sa_handler of signal 7 = Default action sa_handler of signal 8 = Default action sa_handler of signal 9 = Default action sa_handler of signal 10 = 0x8048400 sa_handler of signal 11 = Default action sa_handler of signal 12 = Default action sa_handler of signal 13 = Default action sa_handler of signal 14 = Default action sigaddset(增加一个信号至信号集) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 sigemptyset,sigfillset,sigdelset,sigismember #include int sigaddset(sigset_t *set,int signum); sigaddset()用来将参数 signum 代表的信号加入至参数 set 信号集 里。 执行成功则返回 0,如果有错误则返回-1。 EFAULT 参数 set 指针地址无法存取 EINVAL 参数 signum 非合法的信号编号 sigdelset(从信号集里删除一个信号) 相关函数 表头文件 定义函数 函数说明 sigemptyset,sigfillset,sigaddset,sigismember #include int sigdelset(sigset_t * set,int signum); sigdelset()用来将参数 signum 代表的信号从参数 set 信号集里删 除。 返回值 错误代码 执行成功则返回 0,如果有错误则返回-1。 EFAULT 参数 set 指针地址无法存取 EINVAL 参数 signum 非合法的信号编号 sigemptyset(初始化信号集) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 sigaddset,sigfillset,sigdelset,sigismember #include int sigemptyset(sigset_t *set); sigemptyset()用来将参数 set 信号集初始化并清空。 执行成功则返回 0,如果有错误则返回-1。 EFAULT 参数 set 指针地址无法存取 sigfillset(将所有信号加入至信号集) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 sigempty,sigaddset,sigdelset,sigismember #include int sigfillset(sigset_t * set); sigfillset()用来将参数 set 信号集初始化,然后把所有的信号加入 到此信号集里。 执行成功则返回 0,如果有错误则返回-1。 EFAULT 参数 set 指针地址无法存取 sigismember(测试某个信号是否已加入至信号集里) 相关函数 sigemptyset,sigfillset,sigaddset,sigdelset 表头文件 定义函数 函数说明 返回值 错误代码 #include int sigismember(const sigset_t *set,int signum); sigismember()用来测试参数 signum 代表的信号是否已加入至参 数 set 信号集里。如果信号集里已有该信号则返回 1,否则返回 0。 信号集已有该信号则返回 1,没有则返回 0。如果有错误则返回-1。 EFAULT 参数 set 指针地址无法存取 EINVAL 参数 signum 非合法的信号编号 signal(设置信号处理方式) 相关函数 sigaction,kill,raise 表头文件 #include 定义函数 void (*signal(int signum,void(* handler)(int)))(int); 函数说明 返回值 附加说明 signal()会依参数 signum 指定的信号编号来设置该信号的处理函 数。当指定的信号到达时就会跳转到参数 handler 指定的函数执行。 如果参数 handler 不是函数指针,则必须是下列两个常数之一: SIG_IGN 忽略参数 signum 指定的信号。 SIG_DFL 将参数 signum 指定的信号重设为核心预设的信号处理方 式。 关于信号的编号和说明,请参考附录 D 返回先前的信号处理函数指针,如果有错误则返回 SIG_ERR(1)。 在信号发生跳转到自定的 handler 处理函数执行后,系统会自动将 此处理函数换回原来系统预设的处理方式,如果要改变此操作请改 用 sigaction()。 范例 参考 alarm()或 raise()。 sigpending(查询被搁置的信号) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 signal,sigaction,sigprocmask,sigsuspend #include int sigpending(sigset_t *set); sigpending()会将被搁置的信号集合由参数 set 指针返回。 执行成功则返回 0,如果有错误则返回-1。 EFAULT 参数 set 指针地址无法存取 EINTR 此调用被中断。 sigprocmask(查询或设置信号遮罩) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 signal,sigaction,sigpending,sigsuspend #include int sigprocmask(int how,const sigset_t *set,sigset_t * oldset); sigprocmask()可以用来改变目前的信号遮罩,其操作依参数 how 来决定: SIG_BLOCK 新的信号遮罩由目前的信号遮罩和参数 set 指定的信 号遮罩作联集 SIG_UNBLOCK 将目前的信号遮罩删除掉参数 set 指定的信号遮罩 SIG_SETMASK 将目前的信号遮罩设成参数 set 指定的信号遮罩。 如果参数 oldset 不是 NULL 指针,那么目前的信号遮罩会由此指针 返回。 执行成功则返回 0,如果有错误则返回-1。 EFAULT 参数 set,oldset 指针地址无法存取。 EINTR 此调用被中断 sleep(让进程暂停执行一段时间) 相关函数 signal,alarm 表头文件 定义函数 函数说明 返回值 #include unsigned int sleep(unsigned int seconds); sleep()会令目前的进程暂停,直到达到参数 seconds 所指定的时 间,或是被信号所中断 若进程暂停到参数 seconds 所指定的时间则返回 0,若有信号中断 则返回剩余秒数。 ferror(检查文件流是否有错误发生) 相关函数 表头文件 定义函数 函数说明 返回值 clearerr,perror #include int ferror(FILE *stream); ferror()用来检查参数 stream 所指定的文件流是否发生了错误情 况,如有错误发生则返回非 0 值。 如果文件流有错误发生则返回非 0 值。 perror(打印出错误原因信息字符串) 相关函数 表头文件 定义函数 函数说明 返回值 strerror #include void perror(const char *s); perror ( ) 用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 错 误 (stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因 字符串。此错误原因依照全局变量 errno 的值来决定要输出的字符串。 无 范例 #include main() { FILE *fp; fp = fopen(“/tmp/noexist”,”r+”); if(fp = =NULL) perror(“fopen”); } 执行 $ ./perror fopen : No such file or diretory strerror(返回错误原因的描述字符串) 相关函数 表头文件 定义函数 函数说明 返回值 perror #include char * strerror(int errnum); strerror()用来依参数 errnum 的错误代码来查询其错误原因的描 述字符串,然后将该字符串指针返回。 返回描述错误原因的字符串指针。 范例 /* 显示错误代码 0 至 9 的错误原因描述 */ #include main() { int i; for(i=0;i<10;i++) printf(“%d : %s\n”,i,strerror(i)); } 执行 0 : Success 1 : Operation not permitted 2 : No such file or directory 3 : No such process 4 : Interrupted system call 5 : Input/output error 6 : Device not configured 7 : Argument list too long 8 : Exec format error 9 : Bad file descriptor mkfifo(建立具名管道) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 pipe,popen,open,umask #include #include int mkfifo(const char * pathname,mode_t mode); mkfifo()会依参数 pathname 建立特殊的 FIFO 文件,该文件必须 不存在,而参数 mode 为该文件的权限(mode%~umask),因此 umask 值也会影响到 FIFO 文件的权限。mkfifo()建立的 FIFO 文 件其他进程都可以用读写一般文件的方式存取。当使用 open()来 打开 FIFO 文件时,O_NONBLOCK 旗标会有影响: 1、当使用 O_NONBLOCK 旗标时,打开 FIFO 文件来读取的操作会 立刻返回,但是若还没有其他进程打开 FIFO 文件来读取,则写入 的操作会返回 ENXIO 错误代码。 2、没有使用 O_NONBLOCK 旗标时,打开 FIFO 来读取的操作会等 到其他进程打开 FIFO 文件来写入才正常返回。同样地,打开 FIFO 文件来写入的操作会等到其他进程打开 FIFO 文件来读取后才正常 返回。 若成功则返回 0,否则返回-1,错误原因存于 errno 中。 EACCESS 参数 pathname 所指定的目录路径无可执行的权限 EEXIST 参数 pathname 所指定的文件已存在。 ENAMETOOLONG 参数 pathname 的路径名称太长。 ENOENT 参数 pathname 包含的目录不存在 ENOSPC 文件系统的剩余空间不足 ENOTDIR 参数 pathname 路径中的目录存在但却非真正的目录。 EROFS 参数 pathname 指定的文件存在于只读文件系统内。 范例 #include #include #include main() { char buffer[80]; int fd; unlink(FIFO); mkfifo(FIFO,0666); if(fork()>0){ char s[ ] = “hello!\n”; fd = open (FIFO,O_WRONLY); write(fd,s,sizeof(s)); close(fd); } else{ fd= open(FIFO,O_RDONLY); read(fd,buffer,80); printf(“%s”,buffer); close(fd); } } 执行 hello! pclose(关闭管道 I/O) 相关函数 表头文件 定义函数 函数说明 返回值 popen #include int pclose(FILE * stream); pclose()用来关闭由 popen 所建立的管道及文件指针。参数 stream 为先前由 popen()所返回的文件指针。 返回子进程的结束状态。如果有错误则返回-1,错误原因存于 errno 中。 错误代码 ECHILD pclose()无法取得子进程的结束状态。 范例 参考 popen()。 pipe(建立管道) 相关函数 mkfifo,popen,read,write,fork 表头文件 #include 定义函数 int pipe(int filedes[2]); 函数说明 返回值 pipe()会建立管道,并将文件描述词由参数 filedes 数组返回。 filedes[0]为管道里的读取端,filedes[1]则为管道的写入端。 若成功则返回零,否则返回-1,错误原因存于 errno 中。 错误代码 EMFILE 进程已用完文件描述词最大量 ENFILE 系统已无文件描述词可用。 EFAULT 参数 filedes 数组地址不合法。 范例 /* 父进程借管道将字符串“hello!\n”传给子进程并显示 */ #include main() { int filedes[2]; char buffer[80]; pipe(filedes); if(fork()>0){ /* 父进程*/ char s[ ] = “hello!\n”; write(filedes[1],s,sizeof(s)); } else{ /*子进程*/ read(filedes[0],buffer,80); printf(“%s”,buffer); } } 执行 hello! popen(建立管道 I/O) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 注意事项 范例 pipe,mkfifo,pclose,fork,system,fopen #include FILE * popen( const char * command,const char * type); popen()会调用 fork()产生子进程,然后从子进程中调用/bin/sh -c 来执行参数 command 的指令。参数 type 可使用“r”代表读取, “w”代表写入。依照此 type 值,popen()会建立管道连到子进程 的标准输出设备或标准输入设备,然后返回一个文件指针。随后进 程便可利用此文件指针来读取子进程的输出设备或是写入到子进程 的标准输入设备中。此外,所有使用文件指针(FILE*)操作的函 数也都可以使用,除了 fclose()以外。 若成功则返回文件指针,否则返回 NULL,错误原因存于 errno 中。 EINVAL 参数 type 不合法。 在 编 写 具 SUID/SGID 权 限 的 程 序 时 请 尽 量 避 免 使 用 popen(),popen()会继承环境变量,通过环境变量可能会造成 系统安全的问题。 #include main() { FILE * fp; char buffer[80]; fp=popen(“cat /etc/passwd”,”r”); fgets(buffer,sizeof(buffer),fp); printf(“%s”,buffer); pclose(fp); } 执行 root :x:0 0: root: /root: /bin/bash accept(接受 socket 连线) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 范例 socket,bind,listen,connect #include #include int accept(int s,struct sockaddr * addr,int * addrlen); accept()用来接受参数 s 的 socket 连线。参数 s 的 socket 必需先经 bind()、listen()函数处理过,当有连线进来时 accept()会返 回一个新的 socket 处理代码,往后的数据传送与读取就是经由新的 socket 处理,而原来参数 s 的 socket 能继续使用 accept()来接受 新的连线要求。连线成功时,参数 addr 所指的结构会被系统填入远 程主机的地址数据,参数 addrlen 为 scokaddr 的结构长度。关于结构 sockaddr 的定义请参考 bind()。 成功则返回新的 socket 处理代码,失败返回-1,错误原因存于 errno 中。 EBADF 参数 s 非合法 socket 处理代码。 EFAULT 参数 addr 指针指向无法存取的内存空间。 ENOTSOCK 参数 s 为一文件描述词,非 socket。 EOPNOTSUPP 指定的 socket 并非 SOCK_STREAM。 EPERM 防火墙拒绝此连线 ENOBUFS 系统的缓冲内存不足 ENOMEM 核心内存不足。 参考 listen()。 bind(对 socket 定位) 相关函数 表头文件 定义函数 函数说明 返回值 socket,accept,connect,listen #include #include int bind(int sockfd,struct sockaddr * my_addr,int addrlen); bind()用来设置给参数 sockfd 的 socket 一个名称。此名称由参数 my_addr 指向一 sockaddr 结构,对于不同的 socket domain 定义了一 个通用的数据结构: struct sockaddr { unsigned short int sa_family; char sa_data[14]; }; sa_family 为调用 socket()时的 domain 参数,即 AF_xxxx 值。 sa_data 最多使用 14 个字符长度。 此 sockaddr 结构会因使用不同的 socket domain 而有不同结构定义, 例如使用 AF_INET domain,其 socketaddr 结构定义便为: struct socketaddr_in { unsigned short int sin_family; uint16_t sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; }; struct in_addr { uint32_t s_addr; }; sin_family 即为 sa_family sin_port 为使用的 port 编号 sin_addr.s_addr 为 IP 地址 sin_zero 未使用。 参数 addrlen 为 sockaddr 的结构长度。 成功则返回 0,失败返回-1,错误原因存于 errno 中。 错误代码 范例 参考 listen() EBADF 参数 sockfd 非合法 socket 处理代码。 EACCESS 权限不足 ENOTSOCK 参数 sockfd 为一文件描述词,非 socket。 connect(建立 socket 连线) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 范例 socket,bind,listen #include #include int connect (int sockfd,struct sockaddr * serv_addr,int addrlen); connect()用来将参数 sockfd 的 socket 连至参数 serv_addr 指定的 网络地址。结构 sockaddr 请参考 bind()。参数 addrlen 为 sockaddr 的结构长度。 成功则返回 0,失败返回-1,错误原因存于 errno 中。 EBADF 参数 sockfd 非合法 socket 处理代码 EFAULT 参数 serv_addr 指针指向无法存取的内存空间 ENOTSOCK 参数 sockfd 为一文件描述词,非 socket。 EISCONN 参数 sockfd 的 socket 已是连线状态 ECONNREFUSED 连线要求被 server 端拒绝。 ETIMEDOUT 企图连线的操作超过限定时间仍未有响应。 ENETUNREACH 无法传送数据包至指定的主机。 EAFNOSUPPORT sockaddr 结构的 sa_family 不正确。 EALREADY socket 为不可阻断且先前的连线操作还未完成。 /* 利用 socket 的 TCP client 此程序会连线 TCP server,并将键盘输入的字符串传送给 server。 TCP server 范例请参考 listen()。 */ #include #include #include #include #include #include #include #define PORT 1234 #define SERVER_IP “127.0.0.1” main() { int s; struct sockaddr_in addr; char buffer[256]; if((s = socket(AF_INET,SOCK_STREAM,0))<0){ perror(“socket”); exit(1); } /* 填写 sockaddr_in 结构*/ bzero(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port=htons(PORT); addr.sin_addr.s_addr = inet_addr(SERVER_IP); /* 尝试连线*/ if(connect(s,&addr,sizeof(addr))<0){ perror(“connect”); exit(1); } /* 接收由 server 端传来的信息*/ recv(s,buffer,sizeof(buffer),0); printf(“%s\n”,buffer); while(1){ bzero(buffer,sizeof(buffer)); /* 从标准输入设备取得字符串*/ read(STDIN_FILENO,buffer,sizeof(buffer)); /* 将字符串传给 server 端*/ if(send(s,buffer,sizeof(buffer),0)<0){ perror(“send”); exit(1); } } } 执行 $ ./connect Welcome to server! hi I am client! /*键盘输入*/ /*中断程序*/ endprotoent(结束网络协议数据的读取) 相关函数 表头文件 定义函数 函数说明 返回值 getprotoent,getprotobyname,getprotobynumber,setprotoent #include void endprotoent(void); endprotoent()用来关闭由 getprotoent()打开的文件。 无 范例 参考 getprotoent() endservent(结束网络服务数据的读取) 相关函数 表头文件 getservent,getservbyname,getservbyport,setservent #include 定义函数 函数说明 返回值 void endservent(void); endservent()用来关闭由 getservent()所打开的文件。 无 范例 参考 getservent()。 getsockopt(取得 socket 状态) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 setsockopt #include #include int getsockopt(int s,int level,int optname,void* optval,socklen_t *optlen); getsockopt()会将参数 s 所指定的 socket 状态返回。参数 optname 代表欲取得何种选项状态,而参数 optval 则指向欲保存结果的内存 地址,参数 optlen 则为该空间的大小。参数 level、optname 请参考 setsockopt()。 成功则返回 0,若有错误则返回-1,错误原因存于 errno EBADF 参数 s 并非合法的 socket 处理代码 ENOTSOCK 参数 s 为一文件描述词,非 socket ENOPROTOOPT 参数 optname 指定的选项不正确 EFAULT 参数 optval 指针指向无法存取的内存空间 范例 #include #include main() { int s,optval,optlen = sizeof(int); if((s = socket(AF_INET,SOCK_STREAM,0))<0) perror(“socket”); getsockopt(s,SOL_SOCKET,SO_TYPE,&optval,&optlen); printf(“optval = %d\n”,optval); close(s);} 执行 optval = 1 /*SOCK_STREAM 的定义正是此值*/ htonl(将 32 位主机字符顺序转换成网络字符顺序) 相关函数 表头文件 定义函数 函数说明 返回值 htons,ntohl,ntohs #include unsigned long int htonl(unsigned long int hostlong); htonl()用来将参数指定的 32 位 hostlong 转换成网络字符顺序。 返回对应的网络字符顺序。 范例 参考 getservbyport()或 connect()。 htons(将 16 位主机字符顺序转换成网络字符顺序) 相关函数 表头文件 定义函数 函数说明 返回值 htonl,ntohl,ntohs #include unsigned short int htons(unsigned short int hostshort); htons()用来将参数指定的 16 位 hostshort 转换成网络字符顺序。 返回对应的网络字符顺序。 范例 参考 connect()。 inet_addr(将网络地址转成二进制的数字) 相关函数 表头文件 定义函数 函数说明 返回值 inet_aton,inet_ntoa #include #include #include unsigned long int inet_addr(const char *cp); inet_addr()用来将参数 cp 所指的网络地址字符串转换成网络所 使用的二进制数字。网络地址字符串是以数字和点组成的字符串, 例如:“163.13.132.68”。 成功则返回对应的网络二进制的数字,失败返回-1。 inet_aton(将网络地址转成网络二进制的数字) 相关函数 表头文件 定义函数 函数说明 返回值 inet_addr,inet_ntoa #include #include #include int inet_aton(const char * cp,struct in_addr *inp); inet_aton()用来将参数 cp 所指的网络地址字符串转换成网络使用 的二进制的数字,然后存于参数 inp 所指的 in_addr 结构中。 结构 in_addr 定义如下: struct in_addr { unsigned long int s_addr; }; 成功则返回非 0 值,失败则返回 0。 inet_ntoa(将网络二进制的数字转换成网络地址) 相关函数 表头文件 定义函数 函数说明 返回值 inet_addr,inet_aton #include #include #include char * inet_ntoa(struct in_addr in); inet_ntoa()用来将参数 in 所指的网络二进制的数字转换成网络地 址,然后将指向此网络地址字符串的指针返回。 成功则返回字符串指针,失败则返回 NULL。 listen(等待连接) 相关函数 表头文件 定义函数 函数说明 返回值 附加说明 错误代码 范例 socket,bind,accept,connect #include int listen(int s,int backlog); listen()用来等待参数 s 的 socket 连线。参数 backlog 指定同时能处 理的 最大 连接 要求 ,如 果连 接数 目达 此上 限则 client 端将 收到 ECONNREFUSED 的错误。listen()并未开始接收连线,只是设置 socket 为 listen 模式,真正接收 client 端连线的是 accept()。通常 listen ( ) 会 在 socket ( ) , bind ( ) 之 后 调 用 , 接 着 才 调 用 accept()。 成功则返回 0,失败返回-1,错误原因存于 errno listen()只适用 SOCK_STREAM 或 SOCK_SEQPACKET 的 socket 类型。如果 socket 为 AF_INET 则参数 backlog 最大值可设至 128。 EBADF 参数 sockfd 非合法 socket 处理代码 EACCESS 权限不足 EOPNOTSUPP 指定的 socket 并未支援 listen 模式。 #include #include #include #include #include #define PORT 1234 #define MAXSOCKFD 10 main() { int sockfd,newsockfd,is_connected[MAXSOCKFD],fd; struct sockaddr_in addr; int addr_len = sizeof(struct sockaddr_in); fd_set readfds; char buffer[256]; char msg[ ] =”Welcome to server!”; if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){ perror(“socket”); exit(1); } bzero(&addr,sizeof(addr)); addr.sin_family =AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(sockfd,&addr,sizeof(addr))<0){ perror(“connect”); exit(1); } if(listen(sockfd,3)<0){ perror(“listen”); exit(1); } for(fd=0;fd unsigned long int ntohl(unsigned long int netlong); ntohl()用来将参数指定的 32 位 netlong 转换成主机字符顺序。 返回对应的主机字符顺序。 范例 参考 getservent()。 ntohs(将 16 位网络字符顺序转换成主机字符顺序) 相关函数 表头文件 定义函数 函数说明 返回值 htonl,htons,ntohl #include unsigned short int ntohs(unsigned short int netshort); ntohs()用来将参数指定的 16 位 netshort 转换成主机字符顺序。 返回对应的主机顺序。 范例 参考 getservent()。 recv(经 socket 接收数据) 相关函数 表头文件 定义函数 函数说明 返回值 recvfrom,recvmsg,send,sendto,socket #include #include int recv(int s,void *buf,int len,unsigned int flags); recv()用来接收远端主机经指定的 socket 传来的数据,并把数据 存到由参数 buf 指向的内存空间,参数 len 为可接收数据的最大长 度。 参数 flags 一般设 0。其他数值定义如下: MSG_OOB 接收以 out-of-band 送出的数据。 MSG_PEEK 返 回 来 的 数 据 并 不 会 在 系 统 内 删 除 , 如 果 再 调 用 recv()会返回相同的数据内容。 MSG_WAITALL 强迫接收到 len 大小的数据后才能返回,除非有错 误或信号产生。 MSG_NOSIGNAL 此操作不愿被 SIGPIPE 信号中断 成功则返回接收到的字符数,失败返回-1,错误原因存于 errno 中。 错误代码 范例 参考 listen()。 EBADF 参数 s 非合法的 socket 处理代码 EFAULT 参数中有一指针指向无法存取的内存空间 ENOTSOCK 参数 s 为一文件描述词,非 socket。 EINTR 被信号所中断 EAGAIN 此动作会令进程阻断,但参数 s 的 socket 为不可阻断 ENOBUFS 系统的缓冲内存不足。 ENOMEM 核心内存不足 EINVAL 传给系统调用的参数不正确。 recvfrom(经 socket 接收数据) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 recv,recvmsg,send,sendto,socket #include #include int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr * from ,int *fromlen); recv()用来接收远程主机经指定的 socket 传来的数据,并把数据 存到由参数 buf 指向的内存空间,参数 len 为可接收数据的最大长 度。参数 flags 一般设 0,其他数值定义请参考 recv()。参数 from 用来指定欲传送的网络地址,结构 sockaddr 请参考 bind()。参数 fromlen 为 sockaddr 的结构长度。 成功则返回接收到的字符数,失败则返回 -1,错误原因存于 errno 中。 EBADF 参数 s 非合法的 socket 处理代码 范例 EFAULT 参数中有一指针指向无法存取的内存空间。 ENOTSOCK 参数 s 为一文件描述词,非 socket。 EINTR 被信号所中断。 EAGAIN 此动作会令进程阻断,但参数 s 的 socket 为不可阻断。 ENOBUFS 系统的缓冲内存不足 ENOMEM 核心内存不足 EINVAL 传给系统调用的参数不正确。 /*利用 socket 的 UDP client 此程序会连线 UDP server,并将键盘输入的字符串传给 server。 UDP server 范例请参考 sendto()。 */ #include #include #include #include #include #include #include #define PORT 2345 #define SERVER_IP “127.0.0.1” main() { int s,len; struct sockaddr_in addr; int addr_len =sizeof(struct sockaddr_in); char buffer[256]; /* 建立 socket*/ if((s = socket(AF_INET,SOCK_DGRAM,0))<0){ perror(“socket”); exit(1); } /* 填写 sockaddr_in*/ bzero(&addr,sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = inet_addr(SERVER_IP); while(1){ bzero(buffer,sizeof(buffer)); /* 从标准输入设备取得字符串*/ len =read(STDIN_FILENO,buffer,sizeof(buffer)); /* 将字符串传送给 server 端*/ sendto(s,buffer,len,0,&addr,addr_len); /* 接收 server 端返回的字符串*/ len = recvfrom(s,buffer,sizeof(buffer),0,&addr,&addr_len); printf(“receive: %s”,buffer); } } 执行 (先执行 udp server 再执行 udp client) hello /*从键盘输入字符串*/ receive: hello /*server 端返回来的字符串*/ recvmsg(经 socket 接收数据) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 recv,recvfrom,send,sendto,sendmsg,socket #include #include int recvmsg(int s,struct msghdr *msg,unsigned int flags); recvmsg()用来接收远程主机经指定的 socket 传来的数据。参数 s 为已建立好连线的 socket,如果利用 UDP 协议则不需经过连线操 作。参数 msg 指向欲连线的数据结构内容,参数 flags 一般设 0,详 细 描 述 请 参 考 send ( ) 。 关 于 结 构 msghdr 的 定 义 请 参 考 sendmsg()。 成功则返回接收到的字符数,失败则返回 -1,错误原因存于 errno 中。 EBADF 参数 s 非合法的 socket 处理代码。 EFAULT 参数中有一指针指向无法存取的内存空间 ENOTSOCK 参数 s 为一文件描述词,非 socket。 EINTR 被信号所中断。 EAGAIN 此操作会令进程阻断,但参数 s 的 socket 为不可阻断。 ENOBUFS 系统的缓冲内存不足 ENOMEM 核心内存不足 EINVAL 传给系统调用的参数不正确。 范例 参考 recvfrom()。 send(经 socket 传送数据) 相关函数 sendto,sendmsg,recv,recvfrom,socket 表头文件 定义函数 函数说明 返回值 错误代码 范例 参考 connect() #include #include int send(int s,const void * msg,int len,unsigned int falgs); send()用来将数据由指定的 socket 传给对方主机。参数 s 为已建立 好连接的 socket。参数 msg 指向欲连线的数据内容,参数 len 则为数 据长度。参数 flags 一般设 0,其他数值定义如下: MSG_OOB 传送的数据以 out-of-band 送出。 MSG_DONTROUTE 取消路由表查询 MSG_DONTWAIT 设置为不可阻断运作 MSG_NOSIGNAL 此动作不愿被 SIGPIPE 信号中断。 成功则返回实际传送出去的字符数,失败返回-1。错误原因存于 errno EBADF 参数 s 非合法的 socket 处理代码。 EFAULT 参数中有一指针指向无法存取的内存空间 ENOTSOCK 参数 s 为一文件描述词,非 socket。 EINTR 被信号所中断。 EAGAIN 此操作会令进程阻断,但参数 s 的 socket 为不可阻断。 ENOBUFS 系统的缓冲内存不足 ENOMEM 核心内存不足 EINVAL 传给系统调用的参数不正确。 sendmsg(经 socket 传送数据) 相关函数 表头文件 定义函数 函数说明 send,sendto,recv,recvfrom,recvmsg,socket #include #include int sendmsg(int s,const strcut msghdr *msg,unsigned int flags); sendmsg()用来将数据由指定的 socket 传给对方主机。参数 s 为已 建立好连线的 socket,如果利用 UDP 协议则不需经过连线操作。参 数 msg 指向欲连线的数据结构内容,参数 flags 一般默认为 0,详细 描述请参考 send()。 结构 msghdr 定义如下: 返回值 错误代码 struct msghdr { void *msg_name; /*Address to send to /receive from . */ socklen_t msg_namelen; /* Length of addres data */ strcut iovec * msg_iov; /* Vector of data to send/receive into */ size_t msg_iovlen; /* Number of elements in the vector */ void * msg_control; /* Ancillary dat */ size_t msg_controllen; /* Ancillary data buffer length */ int msg_flags; /* Flags on received message */ }; 成功则返回实际传送出去的字符数,失败返回-1,错误原因存于 errno EBADF 参数 s 非合法的 socket 处理代码。 EFAULT 参数中有一指针指向无法存取的内存空间 ENOTSOCK 参数 s 为一文件描述词,非 socket。 EINTR 被信号所中断。 EAGAIN 此操作会令进程阻断,但参数 s 的 socket 为不可阻断。 ENOBUFS 系统的缓冲内存不足 ENOMEM 核心内存不足 EINVAL 传给系统调用的参数不正确。 范例 参考 sendto()。 sendto(经 socket 传送数据) 相关函数 表头文件 定义函数 函数说明 send , sendmsg,recv , recvfrom , socket #include < sys/types.h > #include < sys/socket.h > int sendto ( int s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ; sendto () 用来将数据由指定的 socket 传给对方主机。参数 s 为已建好 连线的 socket,如果利用 UDP 协议则不需经过连线操作。参数 msg 指 向 欲 连 线 的 数 据 内 容 , 参 数 flags 一 般 设 0 , 详 细 描 述 请 参 考 send()。参数 to 用来指定欲传送的网络地址,结构 sockaddr 请参考 bind().参数 tolen 为 sockaddr 的结果长度。 返回值 错误代码 成功则返回实际传送出去的字符数,失败返回-1,错误原因存于 errno 中。 EBADF 参数 s 非法的 socket 处理代码。 EFAULT 参数中有一指针指向无法存取的内存空间。 WNOTSOCK canshu s 为一文件描述词,非 socket。 EINTR 被信号所中断。 EAGAIN 此动作会令进程阻断,但参数 s 的 soket 为补课阻断的。 ENOBUFS 系统的缓冲内存不足。 EINVAL 传给系统调用的参数不正确。 范例 #include < sys/types.h > #include < sys/socket.h > # include #include #define PORT 2345 /*使用的 port*/ main(){ int sockfd,len; struct sockaddr_in addr; char buffer[256]; /*建立 socket*/ if(sockfd=socket (AF_INET,SOCK_DGRAM,0))<0){ perror (“socket”); exit(1); } /*填写 sockaddr_in 结构*/ bzero ( &addr, sizeof(addr) ); addr.sin_family=AF_INET; addr.sin_port=htons(PORT); addr.sin_addr=hton1(INADDR_ANY) ; if (bind(sockfd, &addr, sizeof(addr))<0){ perror(“connect”); exit(1); } while(1){ bezro(buffer,sizeof(buffer)); len = recvfrom(socket,buffer,sizeof(buffer), 0 , &addr &addr_len); /*显示 client 端的网络地址*/ printf(“receive from %s\n “ , inet_ntoa( addr.sin_addr)); /*将字串返回给 client 端*/ sendto(sockfd,buffer,len,0,&addr,addr_len);” } } 执行 请参考 recvfrom() setprotoent(打开网络协议的数据文件) 相关函数 表头文件 定义函数 函数说明 getprotobyname, getprotobynumber, endprotoent #include void setprotoent (int stayopen); setprotoent() 用来打开/etc/protocols, 如果参数 stayopen 值为 1, 则接下来的 getprotobyname()或 getprotobynumber()将不会自动关闭 此文件。 setservent(打开主机网络服务的数据文件) 相关函数 表头文件 定义函数 函数说明 getservent, getservbyname, getservbyport, endservent #include < netdb.h > void setservent (int stayopen); setservent () 用来打开/etc/services,如果参数 stayopen 值为 1,则接 下来的 getservbyname()或 getservbyport()将补回自动关闭文件。 setsockopt(设置 socket 状态) 相关函数 getsockopt 表头文件 #include 定义函数 函数说明 返回值 #include int setsockopt(int s,int level,int optname,const void * optval,,socklen_t optlen); setsockopt()用来设置参数 s 所指定的 socket 状态。参数 level 代表 欲设置的网络层,一般设成 SOL_SOCKET 以存取 socket 层。参数 optname 代表欲设置的选项,有下列几种数值: SO_DEBUG 打开或关闭排错模式 SO_REUSEADDR 允许在 bind()过程中本地地址可重复使用 SO_TYPE 返回 socket 形态。 SO_ERROR 返回 socket 已发生的错误原因 SO_DONTROUTE 送出的数据包不要利用路由设备来传输。 SO_BROADCAST 使用广播方式传送 SO_SNDBUF 设置送出的暂存区大小 SO_RCVBUF 设置接收的暂存区大小 SO_KEEPALIVE 定期确定连线是否已终止。 SO_OOBINLINE 当接收到 OOB 数据时会马上送至标准输入设备 SO_LINGER 确保数据安全且可靠的传送出去。 参数 optval 代表欲设置的值,参数 optlen 则为 optval 的长度。 成功则返回 0,若有错误则返回-1,错误原因存于 errno。 附加说明 EBADF 参数 s 并非合法的 socket 处理代码 ENOTSOCK 参数 s 为一文件描述词,非 socket ENOPROTOOPT 参数 optname 指定的选项不正确。 EFAULT 参数 optval 指针指向无法存取的内存空间。 范例 参考 getsockopt()。 shutdown(终止 socket 通信) 相关函数 socket,connect 表头文件 定义函数 函数说明 返回值 错误代码 #include int shutdown(int s,int how); shutdown()用来终止参数 s 所指定的 socket 连线。参数 s 是连线中 的 socket 处理代码,参数 how 有下列几种情况: how=0 终止读取操作。 how=1 终止传送操作 how=2 终止读取及传送操作 成功则返回 0,失败返回-1,错误原因存于 errno。 EBADF 参数 s 不是有效的 socket 处理代码 ENOTSOCK 参数 s 为一文件描述词,非 socket ENOTCONN 参数 s 指定的 socket 并未连线 socket(建立一个 socket 通信) 相关函数 表头文件 定义函数 函数说明 accept,bind,connect,listen #include #include int socket(int domain,int type,int protocol); socket()用来建立一个新的 socket,也就是向系统注册,通知系 统建立一通信端口。参数 domain 指定使用何种的地址类型,完整的 定义在/usr/include/bits/socket.h 内,底下是常见的协议: PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 进程通信协议 PF_INET?AF_INET Ipv4 网络协议 PF_INET6/AF_INET6 Ipv6 网络协议 PF_IPX/AF_IPX IPX-Novell 协议 PF_NETLINK/AF_NETLINK 核心用户接口装置 PF_X25/AF_X25 ITU-T X.25/ISO-8208 协议 PF_AX25/AF_AX25 业余无线 AX.25 协议 PF_ATMPVC/AF_ATMPVC 存取原始 ATM PVCs PF_APPLETALK/AF_APPLETALK appletalk(DDP)协议 PF_PACKET/AF_PACKET 初级封包接口 参数 type 有下列几种数值: SOCK_STREAM 提供双向连续且可信赖的数据流,即 TCP。支持 OOB 机制,在所有数据传送前必须使用 connect()来建立连线状 态。 返回值 SOCK_DGRAM 使用不连续不可信赖的数据包连接 SOCK_SEQPACKET 提供连续可信赖的数据包连接 SOCK_RAW 提供原始网络协议存取 SOCK_RDM 提供可信赖的数据包连接 SOCK_PACKET 提供和网络驱动程序直接通信。 参数 protocol 用来指定 socket 所使用的传输协议编号,通常此参考 不用管它,设为 0 即可。 成功则返回 socket 处理代码,失败返回-1。 错误代码 EPROTONOSUPPORT 参数 domain 指定的类型不支持参数 type 或 protocol 指定的协议 ENFILE 核心内存不足,无法建立新的 socket 结构 EMFILE 进程文件表溢出,无法再建立新的 socket EACCESS 权限不足,无法建立 type 或 protocol 指定的协议 ENOBUFS/ENOMEM 内存不足 EINVAL 参数 domain/type/protocol 不合法 范例 参考 connect()。 getenv(取得环境变量内容) 相关函数 表头文件 定义函数 函数说明 返回值 范例 putenv,setenv,unsetenv #include char * getenv(const char *name); getenv()用来取得参数 name 环境变量的内容。参数 name 为环境 变量的名称,如果该变量存在则会返回指向该内容的指针。 环境变量的格式为 name=value。 执行成功则返回指向该内容的指针,找不到符合的环境变量名称则 返回 NULL。 #include mian() { char *p; if((p = getenv(“USER”))) printf(“USER=%s\n”,p); } 执行 USER = root putenv(改变或增加环境变量) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 getenv,setenv,unsetenv #include4 int putenv(const char * string); putenv()用来改变或增加环境变量的内容。参数 string 的格式为 name = value , 如 果 该 环 境 变 量 原 先 存 在 , 则 变 量 内 容 会 依 参 数 string 改变,否则此参数内容会成为新的环境变量。 执行成功则返回 0,有错误发生则返回-1。 ENOMEM 内存不足,无法配置新的环境变量空间 范例 #include main() { char *p; if((p = getenv(“USER”))) printf(“USER =%s\n”,p); putenv(“USER=test”); printf(“USER+5s\n”,getenv(“USER”)); } 执行 USER=root USER=root setenv(改变或增加环境变量) 相关函数 表头文件 定义函数 函数说明 返回值 错误代码 getenv,putenv,unsetenv #include int setenv(const char *name,const char * value,int overwrite); setenv()用来改变或增加环境变量的内容。参数 name 为环境变量 名称字符串,参数 value 则为变量内容,参数 overwrite 用来决定是 否要改变已存在的环境变量。如果 overwrite 不为 0,而该环境变量 原已有内容,则原内容会被改为参数 value 所指的变量内容:如果 overwrite 为 0,且该环境变量已有内容,则参数 value 会被忽略。 执行成功则返回 0,有错误发生时返回-1。 ENOMEM 内存不足,无法配置新的环境变量空间 范例 #include main() { char * p; if((p=getenv(“USER”))) printf(“USER =%s\n”,p); setenv(“USER”,”test”,1); printf(“USER=%s\n”,getenv(“USEr”)); unsetenv(“USER”); printf(“USER=%s\n”,getenv(“USER”)); } 执行 USER = root USER = test USER = (null) getopt(分析命令行参数) 相关函数 表头文件 定义函数 函数说明 返回值 范例 #include 无 #include int getopt(int argc,char * const argv[ ],const char * optstring); getopt()用来分析命令行参数。参数 argc 和 argv 是由 main()传递 的参数个数和内容。参数 optstring 则代表欲处理的选项字符串。此函 数会返回在 argv 中下一个的选项字母,此字母会对应参数 optstring 中的字母。如果选项字符串里的字母后接着冒号“:”,则表示还 有相关的参数,全域变量 optarg 即会指向此额外参数。 如果 getopt()找不到符合的参数则会印出错信息,并将全域变量 optopt 设为“?”字符,如果不希望 getopt()印出错信息,则只 要将全域变量 opterr 设为 0 即可。 如果找到符合的参数则返回此参数字母,如果参数不包含在参数 optstring 的选项字母则返回“?”字符,分析结束则返回-1。 #include int main(int argc,char **argv) { int ch; opterr = 0; while((ch = getopt(argc,argv,”a:bcde”))!= -1) switch(ch) { case ‘a’: printf(“option a:’%s’\n”,optarg); break; case ‘b’: printf(“option b :b\n”); break; default: printf(“other option :%c\n”,ch); } printf(“optopt +%c\n”,optopt); } 执行 $./getopt –b option b:b $./getopt –c other option:c $./getopt –a other option :? $./getopt –a12345 option a:’12345’ isatty(判断文件描述词是否是为终端机) 相关函数 表头文件 定义函数 函数说明 返回值 ttyname #include int isatty(int desc); 如果参数 desc 所代表的文件描述词为一终端机则返回 1,否则返回 0。 如果文件为终端机则返回 1,否则返回 0。 范例 参考 ttyname()。 select(I/O 多工机制) 表头文件 定义函数 函数说明 #include #include #include int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout); select()用来等待文件描述词状态的改变。参数 n 代表最大的文件 描述词加 1,参数 readfds、writefds 和 exceptfds 称为描述词组,是用 来回传该描述词的读,写或例外的状况。底下的宏提供了处理这三 种描述词组的方式: 返回值 FD_CLR(inr fd,fd_set* set);用来清除描述词组 set 中相关 fd 的 位 FD_ISSET(int fd,fd_set *set);用来测试描述词组 set 中相关 fd 的 位是否为真 FD_SET(int fd,fd_set*set);用来设置描述词组 set 中相关 fd 的位 FD_ZERO(fd_set *set); 用来清除描述词组 set 的全部位 参数 timeout 为结构 timeval,用来设置 select()的等待时间,其 结构定义如下: struct timeval { time_t tv_sec; time_t tv_usec; }; 如果参数 timeout 设为 NULL 则表示 select()没有 timeout。 错误代码 执行成功则返回文件描述词状态已改变的个数,如果返回 0 代表在 描述词状态改变前已超过 timeout 时间,当有错误发生时则返回1,错误原因存于 errno,此时参数 readfds,writefds,exceptfds 和 timeout 的值变成不可预测。 EBADF 文件描述词为无效的或该文件已关闭 EINTR 此调用被信号所中断 EINVAL 参数 n 为负值。 ENOMEM 核心内存不足 范例 下面是常见的程序片段 fs_set readset; FD_ZERO(&readset); FD_SET(fd,&readset); select(fd+1,&readset,NULL,NULL,NULL); if(FD_ISSET(fd,readset){……} ttyname(返回一终端机名称) 相关函数 表头文件 定义函数 isatty #include char * ttyname(int desc); 函数说明 返回值 如果参数 desc 所代表的文件描述词为一终端机,则会将此终端机 名称由一字符串指针返回,否则返回 NULL。 如果成功则返回指向终端机名称的字符串指针,有错误情况发生时 则返回 NULL。 范例 #include #include #include #include main() { int fd; char * file = “/dev/tty”; fd = open (fiel,O_RDONLY); printf(“%s”,file); if(isatty(fd)){ printf(“is a tty.\n”); printf(“ttyname = %s \n”,ttyname(fd)); } else printf(“ is not a tty\n”); close(fd); } 执行 /dev/tty is a tty ttyname = /dev/tty

Top_arrow
回到顶部
EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱bbs_service@eeworld.com.cn 或通过站内短信息或QQ:273568022联系管理员 高进,我们会尽快处理。