linux 常用C函数系列之四

8. 数据结构及算法篇
8.1 crypt(将密码或数据编码) 
相关函数  getpass
表头文件  #define _XOPEN_SOURCE
#include<unistd.h>
定义函数  char * crypt (const char *key,const char * salt);
函数说明  crypt()将使用Data Encryption Standard(DES)演算法将参数key所指的字符串加以编码,key

字符串长度仅取前8个字符,超过此长度的字符没有意义。参数salt为两个字符组成的字符串,由a-z、

A-Z、0-9,“.”和“/”所组成,用来决定使用4096 种不同内建表格的哪一个。函数执行成功后会返回指向

编码过的字符串指针,参数key 所指的字符串不会有所更动。编码过的字符串长度为13 个字符,前两

个字符为参数salt代表的字符串。
返回值  返回一个指向以NULL结尾的密码字符串。
附加说明  使用GCC编译时需加-lcrypt。
范例  #include<unistd.h>
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
 

8.2 bsearch(二元搜索) 
相关函数  qsort
表头文件  #include<stdlib.h>
定义函数  void *bsearch(const void *key,const void *base,size_t nmemb,size_tsize,int (*compar) (const

void*,const void*));
函数说明  bsearch()利用二元搜索从排序好的数组中查找数据。参数key指向欲查找的关键数据,参数

base指向要被搜索的数组开头地址,参数nmemb 代表数组中的元素数量,每一元素的大小则由参数

size决定,最后一项参数compar 为一函数指针,这个函数用来判断两个元素之间的大小关系,若传给

compar 的第一个参数所指的元素数据大于第二个参数所指的元素数据则必须回传大于0 的值,两个元

素数据相等则回传0。
附加说明  找到关键数据则返回找到的地址,如果在数组中找不到关键数据则返回NULL。
范例  #include<stdio.h>
#include<stdlib.h>
#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;i<nmemb;i++)
printf(“%s/n”,data[i]);
continue;
}
base = data[0];
qsort(base,nmemb,size,compar);
offset = (char *) bsearch(key,base,nmemb,size,compar);
if( offset = =NULL){
printf(“%s not found!/n”,key);
strcpy(data[nmemb++],key);
printf(“Add %s to data array/n”,key);
}else{
printf(“found: %s /n”,offset);
}
}
}
 
执行  >hello /*输入hello字符串*/
hello not found! /*找不到hello 字符串*/
add hello to data array /*将hello字符串加入*/
>.list /*列出所有数据*/
freebsd
linux
solaris
sunos
windows
hello
>hello
found: hello
 

8.3 lfind(线性搜索) 
相关函数  lsearch
表头文件  #include<stdlib.h>
定义函数  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()。
 

8.4 lsearch(线性搜索) 
相关函数  lfind
表头文件  #include<stdlib.h>
定义函数  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<stdio.h>
#include<stdlib.h>
#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
 
 
8.5 qsort(利用快速排序法排列数组) 
相关函数  bsearch
表头文件  #include<stdlib.h>
定义函数  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 <stdlib.h>
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<nmemb;i++)
printf(“%d “,base[i]);
printf(“/n”);
qsort(base,nmemb,sizeof(int),compar);
for(i=0;i<nmemb;i++)
printf(“%d”base[i]);
printf(“/n”);
}
 
执行  3 102 5 -2 98 52 18
-2 3 5 18 52 98 102
 
 
8.6 rand(产生随机数) 
相关函数  srand,random,srandom
表头文件  #include<stdlib.h>
定义函数  int rand(void
函数说明  rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先

利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。关于随

机数种子请参考srand()。
返回值  返回0至RAND_MAX之间的随机数值,RAND_MAX定义在stdlib.h,其值为2147483647。
范例  /* 产生介于1 到10 间的随机数值,此范例未设随机数种子,完整的随机数产生请参考
srand()*/
#include<stdlib.h>
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
 
 
8.7 srand(设置随机数种子) 
相关函数  rand,random srandom
表头文件  #include<stdlib.h>
定义函数  void srand (unsigned int seed);
函数说明  srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用

geypid()或time(0)的返回值来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会

一样。
返回值 
范例  /* 产生介于1 到10 间的随机数值,此范例与执行结果可与rand()参照*/
#include<time.h>
#include<stdlib.h>
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
 


9.  文件操作篇
9.1 close(关闭文件) 
相关函数  open,fcntl,shutdown,unlink,fclose
表头文件  #include<unistd.h>
定义函数  int close(int fd);
函数说明  当使用完文件后若已不再需要则可使用close()关闭该文件,二close()会让数据写回磁盘,并

释放该文件所占用的资源。参数fd为先前由open()或creat()所返回的文件描述词。
返回值  若文件顺利关闭则返回0,发生错误时返回-1。
错误代码  EBADF 参数fd 非有效的文件描述词或该文件已关闭。
附加说明  虽然在进程结束时,系统会自动关闭已打开的文件,但仍建议自行关闭文件,并确实检查返

回值。
范例  参考open()
 

9.2 creat(建立文件) 
相关函数  read,write,fcntl,close,link,stat,umask,unlink,fopen
表头文件  #include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
定义函数  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()。
 

9.3  dup(复制文件描述词) 
相关函数  open,close,fcntl,dup2
表头文件  #include<unistd.h>
定义函数  int dup (int oldfd);
函数说明  dup()用来复制参数oldfd所指的文件描述词,并将它返回。此新的文件描述词和参数oldfd指

的是同一个文件,共享所有的锁定、读写位置和各项权限或旗标。例如,当利用lseek()对某个文件描述

词作用时,另一个文件描述词的读写位置也会随着改变。不过,文件描述词之间并不共享close-on-

exec旗标。
返回值  当复制成功时,则返回最小及尚未使用的文件描述词。若有错误则返回-1,errno会存放错误代

码。错误代码EBADF参数fd非有效的文件描述词,或该文件已关闭。
 

9.4 dup2(复制文件描述词) 
相关函数  open,close,fcntl,dup
表头文件  #include<unistd.h>
定义函数  int dup2(int odlfd,int newfd);
函数说明  dup2()用来复制参数oldfd所指的文件描述词,并将它拷贝至参数newfd后一块返回。若参数

newfd为一已打开的文件描述词,则newfd所指的文件会先被关闭。dup2()所复制的文件描述词,与原来

的文件描述词共享各种文件状态,详情可参考dup()。
返回值  当复制成功时,则返回最小及尚未使用的文件描述词。若有错误则返回-1,errno会存放错误代

码。
附加说明  dup2()相当于调用fcntl(oldfd,F_DUPFD,newfd);请参考fcntl()。
错误代码  EBADF 参数fd 非有效的文件描述词,或该文件已关闭
 
 
9.5 fcntl(文件描述词操作) 
相关函数  open,flock
表头文件  #include<unistd.h>
#include<fcntl.h>
定义函数  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.
 
 
9.6 flock(锁定文件或解除锁定) 
相关函数  open,fcntl
表头文件  #include<sys/file.h>
定义函数  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。
 

9.7 fsync(将缓冲区数据写回磁盘) 
相关函数  sync
表头文件  #include<unistd.h>
定义函数  int fsync(int fd);
函数说明  fsync()负责将参数fd所指的文件数据,由系统缓冲区写回磁盘,以确保数据同步。
返回值  成功则返回0,失败返回-1,errno为错误代码。
 

9.8 lseek(移动文件的读写位置) 
相关函数  dup,open,fseek
表头文件  #include<sys/types.h>
#include<unistd.h>
定义函数  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。
范例  参考本函数说明
 

9.9 mkstemp(建立唯一的临时文件) 
相关函数  mktemp
表头文件  #include<stdlib.h>
定义函数  int mkstemp(char * template);
函数说明  mkstemp()用来建立唯一的临时文件。参数template 所指的文件名称字符串中最后六个字符

必须是XXXXXX。Mkstemp()会以可读写模式和0600 权限来打开该文件,如果该文件不存在则会建立

该文件。打开该文件后其文件描述词会返回。文件顺利打开后返回可读写的文件描述词。若果文件打

开失败则返回NULL,并把错误代码存在errno 中。
错误代码  EINVAL 参数template 字符串最后六个字符非XXXXXX。EEXIST 无法建立临时文件。
附加说明  参数template所指的文件名称字符串必须声明为数组,如:
char template[ ] =”template-XXXXXX”;
千万不可以使用下列的表达方式
char *template = “template-XXXXXX”;
范例  #include<stdlib.h>
main( )
{
int fd;
char template[ ]=”template-XXXXXX”;
fd=mkstemp(template);
printf(“template = %s/n”,template);
close(fd);
}
 
执行  template = template-lgZcbo
 
 
9.10 open(打开文件) 
相关函数  read,write,fcntl,close,link,stat,umask,unlink,fopen
表头文件  #include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
定义函数  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<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
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!
 
 
9.11 read(由已打开的文件读取数据) 
相关函数  readdir,write,fcntl,close,lseek,readlink,fread
 
表头文件  #include<unistd.h>
 
定义函数  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()。
 

9.12 sync(将缓冲区数据写回磁盘) 
相关函数  fsync
表头文件  #include<unistd.h>
定义函数  int sync(void)
函数说明  sync()负责将系统缓冲区数据写回磁盘,以确保数据同步。
返回值  返回0。
 

9.13 write(将数据写入已打开的文件内) 
相关函数  open,read,fcntl,close,lseek,sync,fsync,fwrite
表头文件  #include<unistd.h>
定义函数  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()。
 


10. 文件内容操作篇
10.1 clearerr(清除文件流的错误旗标) 
相关函数  feof
表头文件  #include<stdio.h>
定义函数  void clearerr(FILE * stream);
函数说明  clearerr()清除参数stream指定的文件流所使用的错误旗标。
返回值 
 
 
10.2 fclose(关闭文件) 
相关函数  close,fflush,fopen,setbuf
表头文件  #include<stdio.h>
定义函数  int fclose(FILE * stream);
函数说明  fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系

统所提供的文件资源。
返回值  若关文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno。
错误代码  EBADF表示参数stream非已打开的文件。
范例  请参考fopen()。
 

10.3 fdopen(将文件描述词转为文件指针) 
相关函数  fopen,open,fclose
表头文件  #include<stdio.h>
定义函数  FILE * fdopen(int fildes,const char * mode);
函数说明  fdopen()会将参数fildes 的文件描述词,转换为对应的文件指针后返回。参数mode 字符串则

代表着文件指针的流形态,此形态必须和原先文件描述词读写模式相同。关于mode 字符串格式请参考

fopen()。
返回值  转换成功时返回指向该流的文件指针。失败则返回NULL,并把错误代码存在errno中。
范例  #include<stdio.h>
main()
{
FILE * fp =fdopen(0,”w+”);
fprintf(fp,”%s/n”,”hello!”);
fclose(fp);
}
 
执行  hello!
 

10.4 feof(检查文件流是否读到了文件尾) 
相关函数  fopen,fgetc,fgets,fread
表头文件  #include<stdio.h>
定义函数  int feof(FILE * stream);
函数说明  feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返回之文件指针。如果已到

文件尾则返回非零值,其他情况返回0。
返回值  返回非零值代表已到达文件尾。
 

10.5 fflush(更新缓冲区) 
相关函数  write,fopen,fclose,setbuf
表头文件  #include<stdio.h>
定义函数  int fflush(FILE* stream);
函数说明  fflush()会强迫将缓冲区内的数据写回参数stream指定的文件中。如果参数stream为NULL,

fflush()会将所有打开的文件数据更新。
返回值  成功返回0,失败返回EOF,错误代码存于errno中。
错误代码  EBADF 参数stream 指定的文件未被打开,或打开状态为只读。其它错误代码参考write()


 

10.6 fgetc(由文件中读取一个字符) 
相关函数  open,fread,fscanf,getc
表头文件  include<stdio.h>
定义函数  nt fgetc(FILE * stream);
函数说明  fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。
返回值  getc()会返回读取到的字符,若返回EOF则表示到了文件尾。
范例  #include<stdio.h>
main()
{
FILE *fp;
int c;
fp=fopen(“exist”,”r”);
while((c=fgetc(fp))!=EOF)
printf(“%c”,c);
fclose(fp);
}
 
 
10.7 fgets(由文件中读取一字符串) 
相关函数  open,fread,fscanf,getc
表头文件  include<stdio.h>
定义函数  har * fgets(char * s,int size,FILE * stream);
函数说明  fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行

字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。
返回值  gets()若成功则返回s指针,返回NULL则表示有错误发生。
范例  #include<stdio.h>
main()
{
char s[80];
fputs(fgets(s,80,stdin),stdout);
}
 
执行  this is a test /*输入*/
this is a test /*输出*/
 

10.8 fileno(返回文件流所使用的文件描述词) 
相关函数  open,fopen
表头文件  #include<stdio.h>
定义函数  int fileno(FILE * stream);
函数说明  fileno()用来取得参数stream指定的文件流所使用的文件描述词。
返回值  返回文件描述词。
范例  #include<stdio.h>
main()
{
FILE * fp;
int fd;
fp=fopen(“/etc/passwd”,”r”);
fd=fileno(fp);
printf(“fd=%d/n”,fd);
fclose(fp);
}
 
执行  fd=3
 

10.9 fopen(打开文件) 
相关函数  open,fclose
表头文件  #include<stdio.h>
定义函数  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<stdio.h>
main()
{
FILE * fp;
fp=fopen(“noexist”,”a+”);
if(fp= =NULL) return;
fclose(fp);
}
 

10.10 fputc(将一指定字符写入文件流中) 
相关函数  fopen,fwrite,fscanf,putc
表头文件  #include<stdio.h>
定义函数  int fputc(int c,FILE * stream);
函数说明  fputc 会将参数c 转为unsigned char 后写入参数stream 指定的文件中。
返回值  fputc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
范例  #include<stdio.h>
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);
}
 
 
10.11 fputs(将一指定的字符串写入文件内) 
相关函数  fopen,fwrite,fscanf,fputc,putc
表头文件  #include<stdio.h>
定义函数  int fputs(const char * s,FILE * stream);
函数说明  fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。
返回值  若成功则返回写出的字符个数,返回EOF则表示有错误发生。
范例  请参考fgets()。
 

10.12 fread(从文件流读取数据) 
相关函数  fopen,fwrite,fseek,fscanf
表头文件  #include<stdio.h>
定义函数  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<stdio.h>
#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<nmemb;i++)
printf(“name[%d]=%-20s:size[%d]=%d/n”,i,s[i].name,i,s[i].size);
}
 
执行  name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8
name[2]=Windows2000 size[2]=11
 

10.13 freopen(打开文件) 
相关函数  fopen,fclose
表头文件  #include<stdio.h>
定义函数  FILE * freopen(const char * path,const char * mode,FILE * stream);
函数说明  参数path字符串包含欲打开的文件路径及文件名,参数mode请参考fopen()说明。参数stream

为已打开的文件指针。Freopen()会将原stream所打开的文件流关闭,然后打开参数path的文件。
返回值  文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错

误代码存在errno 中。
范例  #include<stdio.h>
main()
{
FILE * fp;
fp=fopen(“/etc/passwd”,”r”);
fp=freopen(“/etc/group”,”r”,fp);
fclose(fp);
}
 

10.14 fseek(移动文件流的读写位置) 
相关函数  rewind,ftell,fgetpos,fsetpos,lseek
表头文件  #include<stdio.h>
定义函数  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<stdio.h>
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
 

10.15 ftell(取得文件流的读取位置) 
相关函数  fseek,rewind,fgetpos,fsetpos
表头文件  #include<stdio.h>
定义函数  long ftell(FILE * stream);
函数说明  ftell()用来取得文件流目前的读写位置。参数stream为已打开的文件指针。
返回值  当调用成功时则返回目前的读写位置,若有错误则返回-1,errno会存放错误代码
错误代码  EBADF 参数stream无效或可移动读写位置的文件流。
范例  参考fseek()。
 

10.16 fwrite(将数据写至文件流) 
相关函数  fopen,fread,fseek,fscanf
表头文件  #include<stdio.h>
定义函数  size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);
函数说明  fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr 指向欲写入的数

据地址,总共写入的字符数以参数size*nmemb来决定。Fwrite()会返回实际写入的nmemb数目。
返回值  返回实际写入的nmemb数目。
范例  #include<stdio.h>
#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()。
 

10.17 getc(由文件中读取一个字符) 
相关函数  read,fopen,fread,fgetc
表头文件  #include<stdio.h
定义函数  int getc(FILE * stream);
函数说明  getc()用来从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF

。虽然getc()与fgetc()作用相同,但getc()为宏定义,非真正的函数调用。
返回值  getc()会返回读取到的字符,若返回EOF则表示到了文件尾。
范例  参考fgetc()。
 

10.18 getchar(由标准输入设备内读进一字符) 
相关函数  fopen,fread,fscanf,getc
表头文件  #include<stdio.h>
定义函数  int getchar(void);
函数说明  getchar()用来从标准输入设备中读取一个字符。然后将该字符从unsigned char转换成int后返

回。
返回值  getchar()会返回读取到的字符,若返回EOF则表示有错误发生。
附加说明  getchar()非真正函数,而是getc(stdin)宏定义。
范例  #include<stdio.h>
main()
{
FILE * fp;
int c,i;
for(i=0li<5;i++)
{
c=getchar();
putchar(c);
}
}
 
执行  1234 /*输入*/
1234 /*输出*/
 

10.19 gets(由标准输入设备内读进一字符串) 
相关函数  fopen,fread,fscanf,fgets
表头文件  #include<stdio.h>
定义函数  char * gets(char *s);
函数说明  gets()用来从标准设备读入字符并存到参数s所指的内存空间,直到出现换行字符或读到文件

尾为止,最后加上NULL作为字符串结束。
返回值  gets()若成功则返回s指针,返回NULL则表示有错误发生。
附加说明  由于gets()无法知道字符串s的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造

成缓冲溢出的安全性问题。建议使用fgets()取代。
范例  参考fgets()
 

10.20 mktemp(产生唯一的临时文件名) 
相关函数  tmpfile
表头文件  #include<stdlib.h>
定义函数  char * mktemp(char * template);
函数说明  mktemp()用来产生唯一的临时文件名。参数template所指的文件名称字符串中最后六个字符

必须是XXXXXX。产生后的文件名会借字符串指针返回。
返回值  文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错

误代码存在errno中。
附加说明  参数template所指的文件名称字符串必须声明为数组,如:
char template[ ]=”template-XXXXXX”;
不可用char * template=”template-XXXXXX”;
范例  #include<stdlib.h>
main()
{
char template[ ]=”template-XXXXXX”;
mktemp(template);
printf(“template=%s/n”,template);
}
 

10.21 putc(将一指定字符写入文件中) 
相关函数  fopen,fwrite,fscanf,fputc
表头文件  #include<stdio.h>
定义函数  int putc(int c,FILE * stream);
函数说明  putc()会将参数c转为unsigned char后写入参数stream指定的文件中。虽然putc()与fputc()作用

相同,但putc()为宏定义,非真正的函数调用。
返回值  putc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。
范例  参考fputc()。
 
 
10.22 putchar(将指定的字符写到标准输出设备) 
相关函数  fopen,fwrite,fscanf,fputc
表头文件  #include<stdio.h>
定义函数  int putchar (int c);
函数说明  putchar()用来将参数c字符写到标准输出设备。
返回值  putchar()会返回输出成功的字符,即参数c。若返回EOF则代表输出失败。
附加说明  putchar()非真正函数,而是putc(c,stdout)宏定义。
范例  参考getchar()。
 
 
10.23 rewind(重设文件流的读写位置为文件开头) 
相关函数  fseek,ftell,fgetpos,fsetpos
表头文件  #include<stdio.h>
定义函数  void rewind(FILE * stream);
函数说明  rewind()用来把文件流的读写位置移至文件开头。参数stream为已打开的文件指针。此函数

相当于调用fseek(stream,0,SEEK_SET)。
返回值 
范例  参考fseek()
 

10.24 setbuf(设置文件流的缓冲区) 
相关函数  setbuffer,setlinebuf,setvbuf
表头文件  #include<stdio.h>
定义函数  void setbuf(FILE * stream,char * buf);
函数说明  在打开文件流后,读取内容之前,调用setbuf()可以用来设置文件流的缓冲区。参数stream为

指定的文件流,参数buf指向自定的缓冲区起始地址。如果参数buf为NULL指针,则为无缓冲IO。

Setbuf()相当于调用:setvbuf(stream,buf,buf?_IOFBF:_IONBF,BUFSIZ)
返回值 
 

10.25 setbuffer(设置文件流的缓冲区) 
相关函数  setlinebuf,setbuf,setvbuf
表头文件  #include<stdio.h>
定义函数  void setbuffer(FILE * stream,char * buf,size_t size);
函数说明  在打开文件流后,读取内容之前,调用setbuffer()可用来设置文件流的缓冲区。参数stream为

指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小。
返回值 
 
 
10.26 setlinebuf(设置文件流为线性缓冲区) 
相关函数  setbuffer,setbuf,setvbuf
表头文件  #include<stdio.h>
定义函数  void setlinebuf(FILE * stream);
函数说明  setlinebuf()用来设置文件流以换行为依据的无缓冲IO。相当于调用:setvbuf(stream,(char * )

NULL,_IOLBF,0);请参考setvbuf()。
返回值 
 

10.27 setvbuf(设置文件流的缓冲区) 
相关函数  setbuffer,setlinebuf,setbuf
表头文件  #include<stdio.h>
定义函数  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。
 

10.28 ungetc(将指定字符写回文件流中) 
相关函数  fputc,getchar,getc
表头文件  #include<stdio.h>
定义函数  int ungetc(int c,FILE * stream);
函数说明  ungetc()将参数c字符写回参数stream所指定的文件流。这个写回的字符会由下一个读取文件

流的函数取得。
返回值  成功则返回c 字符,若有错误则返回EOF。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值