atoi 名字来源:array to integer 的缩写. 原型: int atoi(const char *nptr); 函数说明: 参数nptr字符串,如果第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。 程序例: 1) #include <stdlib.h> #include <stdio.h> int main(void) { int n; char *str = "12345.67"; n = atoi(str); printf("string = %s integer = %d\n", str, n); return 0; } 执行结果 string = 12345.67 integer = 12345 2) #include <stdlib.h> #include <stdio.h> int main() { char a[] = "-100" ; char b[] = "123" ; int c ; c = atoi( a ) + atoi( b ) ; printf("c = %d\n", c) ; return 0; } 执行结果 c = 23 #include <cctype> int my_atoi(const char* p){ assert(p != NULL); bool neg_flag = false;// 符号标记 int res = 0;// 结果 if(p[0] == '+' || p[0] == '-') neg_flag = (*p++ != '+'); while(isdigit(*p)) res = res*10 + (*p++ - '0'); return neg_flag ?0 -res : res; } feof目录 函数名 feof 功 能 检测流上的文件结束符 The function feof() tests theend-of-file indicator for the stream pointed to by stream, returning non-zeroif it is set. The end-of-file indicator can only be cleared by thefunction clearerr(). 用 法 int feof(FILE *stream); 程序例 int main(void) { FILE *stream; /* open a file for reading */ stream = fopen("DUMMY.FIL","r"); /* read a character from the file */ fgets(stream); /* check for EOF */ if (feof(stream)) printf("We have reachedend-of-file\n"); /* close the file */ fclose(stream); return 0; } feof(fp)有两个返回值:如果遇到文件结束,函数feof(fp)的值为非零值,否则为0。 EOF是文本文件结束的标志。在文本文件中,数据是以 字符的ASCⅡ代码值的形式存放,普通字符的ASCⅡ代码的范围是32到127(十进制),EOF的16进制代码为0x1A(十进制为26),因此可以用EOF作为文件结束标志。 当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。为解决这一个问题,ASCI C提供一个feof函数,用来判断文件是否结束。feof函数既可用以判断二进制文件又可用以判断文本文件。 “C”语言的“feof()”函数和数据库中“eof()”函数的运做是完全不同的。数据库中“eof()”函数读取当前 指针的位置,“C”语言的“feof()”函数返回的是最后一次“读操作的内容”。多年来把“位置和内容”相混,从而造成了对这一概念的似是而非。 那么,位置和内容到底有何不同呢?举个简单的例子, 比如有人说“你走到火车的最后一节车箱”这就是位置。而如果说“请你一直向后走,摸到铁轨结束”这就是内容。也就是说用内容来判断会“多走一节”。这就是完全依赖于“while(!feof(FP)){...}”进行文件复制时,目标文档总会比源文档“多出一些”的原因。 在“C”文件读取操作时不能完全依赖于“while(!feof(FP)){...}”的判断。下面代码是改进后的代码,该代码执行后output文件内容和input文件内容一致,与使用“while(!feof(FP)){...}”相比,input文件的结尾符号(EOF)没有被读入到output文件中。 //main.c linux 下编译通过。 int main(void) { FILE *in, *out; int ch; if ((in = fopen("./input.txt","r"))== NULL) //input.txt must exist in current directory. { fprintf(stderr, "Cannot openinputfile\n"); exit(0); } if((out=fopen("./output.txt","w"))==NULL) { fprintf(stderr,"Can not open thefile.\n"); exit(0); } while(1) { ch=fgetc(in); if(ch == -1) break; fprintf(stdout,"The ASC of char %cis %d\n ",ch,ch); fputc(ch,out); } fclose(in); fclose(out); return 0; } 与EOF的区别 在stdio.h中可以看到如下定义: #define EOF (-1) #define _IOEOF 0x0010 #define feof(_stream)((_stream)->_flag & _IOEOF) int c; while(!feof(fp)) { c = fgetc(fp); printf("%X\n", c); } 会发现多输出了一个FF,原因就是在读完最后一个字符后,fp->flag仍然没有被置为_IOEOF,因而feof()仍然没有探测到文件结尾。直到再次调用fgetc()执行读操作,feof()才能探测到文件结尾。这样就多输出了一个-1(即FF)。 正确的写法应该是: int c; c = fgetc(fp); while(!feof(fp)) { printf("%X\n", c); c = fgetc(fp); } feof()可以用EOF代替吗?不可以。fgetc返回-1时,有两种情况:读到文件结尾或是读取错误。因此我们无法确信文件已经结束, 因为可能是读取错误! 这时我们需要feof()。 Strstr 函数名: strstr 函数原型:extern char *strstr(char *str1, char*str2); 功能:找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符)。 Exit()函数名: exit() 所在头文件:stdlib.h 功 能: 关闭所有文件,终止正在执行的程序。 exit(1)表示异常退出.这个1是返回给操作系统的不过在DOS好像不需要这个返回值 exit(x)(x不为0)都表示异常退出 exit(0)表示正常退出 定义函数: int stat(const char*file_name, struct stat *buf); Stat函数说明: 通过文件名filename获取文件信息,并保存在buf所指的结构体stat中 返回值: 执行成功则返回0,失败返回-1,错误代码存于errno 错误代码: ENOENT 参数file_name指定的文件不存在 ENOTDIR 路径中的目录存在但却非真正的目录 ELOOP 欲打开的文件有过多符号连接问题,上限为16符号连接 EFAULT 参数buf为无效指针,指向无法存在的内存空间 EACCESS 存取文件时被拒绝 ENOMEM 核心内存不足 ENAMETOOLONG 参数file_name的路径名称太长 System()相关函数
fork,execve,waitpid,popen
表头文件
#include<stdlib.h>
定义函数
int system(const char * string);
函数说明
system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
返回值
=-1:出现错误
=0:调用成功但是没有出现子进程
>0:成功退出的子进程的id
如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值>。 如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。
附加说明
在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。 Time()1970年1月1日0点以来的秒 htons: 将一个无符号短整型数值转换为网络字节序,即大端模式。 htonl:将主机的无符号长整型数转换成网络字节顺序。 getSystemTime()但是必须注意,该函数返回的是格林威治标准时间,而并不是用户所在时区的时间,所以在使用时需要进行相应的转换计算! fdopen函数 相关函数:fopen,open,fclose 表头文件:#include<stdio.h> 定义函数:FILE * fdopen(int fildes,const char * mode); 函数说明: fdopen 取一个现存的文件描述符(我 们可能从 o p e n , d u p, d u p 2 , f c n t l 或p i p e 函数得到此文件描述符),并使一个标准的I / O 流与该描述符相结合。此函数常用于由创建管道和网络通信通道函数获得的描述符。因为这些特殊类型的文件不能用标准I/O fopen 函数打开,首先必须先调用设备专用函数以获得一个文件描述符,然后用f d o p e n 使一个标准I / O 流与该描述符相结合。 fdopen() 会将参数fildes 的文件描述词,转换为对应的文件指针后返回。参数mode 字符串 则代表着文件指针的流形态,此形态必须和原先文件描述词读写模式相同。 mode有下列几种形态字符串: r+ 打开可读写的文件,该文件必须存在。 w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。 w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。 a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。 a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 对于f d o p e n,t y p e参数的意义则稍有区别。因为该描述符已被打开,所以 f d o p e n为写而打开并不截短该文件。(例如,若该描述符原来是由 o p e n函数打开的,该文件那时已经存在,则其O _ T R U N C标志将决定是否截短该文件。f d o p e n函数不能截短它为写而打开的任一文件。)另外,标准I / O添加方式也不能用于创建该文件(因为如若一个描述符引用一个文件,则该文件一定已经存在)。 上述的形态字符串都可以再加一个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 中。 范例:#include<stdio.h> main() { FILE * fp =fdopen(0,”w+”); fprintf(fp,”%s\n”,”hello!”); fclose(fp); } 执行:hello! dup() dup2() int dup(int fd); int dup2(int fd1 ,int fd2 ); 两个均为复制一个现存的文件的描述 两个函数的返回:若成功为新的文件描述,若出错为-1; 由dup返回的新 文件描述符一定是当前可用文件描述中的最小数值。用dup2则可以用fd2参数指定新的描述符数值。如果fd2已经打开,则先关闭。若fd1=fd2,则dup2返回fd2,而不关闭它。通常使用这两个系统调用来重定向一个打开的文件描述符 fcntl 定义函数 int fcntl(int fd , int cmd,...); 函数是变参函数,根据cmd 来判断第三个参数,参见printf 的运用 参数介绍 1. 参数fd 参数fd代表欲设置的文件描述词。 2. 参数cmd 参数cmd代表打算操作的指令。 有以下几种情况: F_DUPFD 用来查找大于或等于参数arg 的最小且仍未使用的文件描述词,并且复制参数fd 的文件描述词。执行成功则返回新复制的文件描述词。新描述符与fd 共享同一文件表项,但是新描述符有它自己的一套文件描述符标志,其中FD_CLOEXEC 文件描述符标志被清除。请参考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。 3. 参数lock指针 参数lock指针为flock 结构指针,定义如下 struct flock { short int l_type; short int l_whence; 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. fcntl() 用来操作文件描述符的一些特性。fcntl 不仅可以施加建议性锁,还可以施加强制锁。同时,fcntl 还能对文件的某一记录进行上锁,也就是记录锁。 fcntl 的返回值与命令有关。如果出错,所有命令都返回-1 ,如果成功则返回某个其他值。下列四个命令有特定返回值:F_DUPFD 、F_GETFD 、F_GETFL 、F_GETOWN. 第一个返回新的文件描述符,接下来的两个返回相应标志,最后一个返回一个正的进程ID 或负的进程组ID 。 [1] int flags; /* 设置为非阻塞*/ if ((flags = fcntl(sock_descriptor, F_GETFL, 0)) < 0) { /* Handle error */ } if (fcntl(socket_descriptor, F_SETFL, flags | O_NONBLOCK) < 0) { /* Handle error */ } /* 设置为阻塞 */ if ((flags = fcntl(sock_descriptor, F_GETFL, 0)) < 0) { /* Handle error */ } if (fcntl(socket_descriptor, F_SETFL, flags & (~O_NONBLOCK))< 0) { /* Handle error */ }
|