C Library
Table of Contents
1 math
- ceil(2.5)
- floor(2.5)
- round(2.5)
2 signal.h
signal
/** * sig * SIGABRT Signal Abort 中止 * SIGFPE Floating-Point-Exception 浮点数异常 * SIGILL Illegal Instruction 不合法指令 * SIGINT Interrupt 中断 * SIGSEGV Segmentation Violation 段错误 * SIGTERM Terminate 中止 * SIGPIPE Broken pipe 管道错误 */ /** * `SIGPIPE`: one process open a pipe or FIFO for reading before another wrote to it. If the reading process never starts, or terminates unexpectly, writing to it raises SIGPIPE. Or output to a socket that isn't connected. */ /** * func * SIG_DFL default * SIG_IGN Ignore * customize: void handler_function(int parameter) */ void (*signal(int sig, void (*func)(int))) (int);
3 socket
3.1 API
socket
// domain: AF_INET(IPv4), AF_INET6(IPv6) // type: SOCK_STREAM, SOCK_DGRAM // protocol: end-to-end protocol. IPPROTO_TCP, IPPROTO_UDP int socket(int domain, int type, int protocol);
inet_pton
// src: "192.168.1.1" // dst: *数字 inet_pton(int addressFamily, const char *src, void *dst);
inet_ntop
// 数字 => "192.168.1.1" // socklen_t: INET_ADDRSTRLEN IPv4可能最长的结果字符串(字节) const char *inet_ntop(int addressFamily, const void *src, char *dst, socklen_t dstBytes);
htons
// convert hostshort from host byte order to network byte order. uint16_t htons(unit16_t hostshort);
connect
// foreignAddr: (struct sockaddr *)&[sockaddr_in] // addressLength: sizeof(struct sockaddr_in); int connect(int socket, const struct sockaddr *foreignAddress, socklen_t addressLength);
3.1.1 Server
bind
int bind(int socket, struct sockaddr *localAddress, socklen_t addressSize);
listen
// 告诉TCP实现允许来自客户的连接 // 调用之前,任何连接请求被无声拒绝 int listen(int socket, int queueLimit);
accept
// 使套接字队列中的下一条连接出队。若队列空,则阻塞。 int accept(int socket, struct sockaddr *clientAddress, socklen_t *addressLength); // 正确的使用方式: struct sockaddr_storage address; socklen_t addrLength = sizeof(address); int clntSock = accept(sock, &address, &addressLength); // 其中结构体定义如下 struct sockaddr_storage { sa_familiy_t ... // Padding and fields to get correct length and allignment }; // 通用地址存储器
send
// 默认阻塞到发送了所有的数据为止。 // 返回:发送的字节数 // flags:改变默认行为。默认为0. ssize_t send(int socket, const void *msg, size_t msgLength, int flags);
recv
// 默认阻塞到至少传输了一些字节为止。 // 返回:接受的字节数 ssize_t recv(int socket, void *rcvBuffer, size_t bufferLength, int flags);
3.2 Code Snippets
3.2.1 TCP client
#include <stdlib.h> #include <stdio.h> #include <string.h> // for memset #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> // for IPPROTO_TCP #include <unistd.h> // for close. use `man close` #include <arpa/inet.h> #define BUFFER_SIZE 30 int main() { // 创建socket int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 构造servAddr char *servIP = "127.0.0.1"; in_port_t servPort = 8080; struct sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; // IP地址格式转换 inet_pton(AF_INET, servIP, &servAddr.sin_addr.s_addr); servAddr.sin_port = htons(servPort); // 建立连接 connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)); char str[] = "Hello"; size_t size = strlen(str); // 发送数据 send(sock, str, size, 0); char buffer[BUFFER_SIZE]; // 接收返回的数据,放到buffer里 recv(sock, buffer, BUFFER_SIZE-1, 0); // 关闭socket close(sock); }
3.2.2 TCP server
#include <stdlib.h> #include <stdio.h> #include <string.h> // for memset #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> // for IPPROTO_TCP #include <unistd.h> // for close. use `man close` #define BUFSIZE 30 void handle(int clntSock) { char buffer[BUFSIZE]; // 从client端socket接收数据,存入buffer,返回接受长度。一次只收BUFSIZE个字节。 ssize_t numBytesRcvd = recv(clntSock, buffer, BUFSIZE, 0); // 循环接收直到收完为止。 while(numBytesRcvd>0) { // 将接收到的buffer,send到client端buffer send(clntSock, buffer, numBytesRcvd, 0); // 接着接收没收完的。 numBytesRcvd = recv(clntSock, buffer, BUFSIZE, 0); } // 关闭socket close(clntSock); } int main(){ // 创建socket int servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // 构造servAddr in_port_t servPort = 8080; struct sockaddr_in servAddr; memset(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // any incoming interface servAddr.sin_port = htons(servPort); // socket绑定到servAddr bind(servSock, (struct sockaddr *)&servAddr, sizeof(servAddr)); // 监听socket listen(servSock, 5); for(;;) { struct sockaddr_in clntAddr; socklen_t clntAddrLen = sizeof(clntAddr); // 接受socket来的请求,把来的socket存入clntSock int clntSock = accept(servSock, (struct sockaddr *)&clntAddr, &clntAddrLen); // 处理之 handle(clntSock); } }
4 stdio
4.1 stdio.h
perror
void perror(const char *str);
fflush
int fflush(FILE *stream);
fopen
FILE *fopen(const char *filename, const char *mode);
fclose
int fclose(FILE *stream);
freopen
FILE *freopen(const char *filename, const char *mode, FILE *stream);
fprintf
int fprintf(FILE *stream, const char *format, ...);
fscanf
int fscanf(FILE *stream, const char *format, ...);
4.2 examples
#include <stdio.h> int main() { FILE* p = fopen("a.txt", "w"); fprintf(p, "hello"); fclose(p); }
5 stdlib
5.1 stdlib.h
malloc
// Allocates a block of size bytes of memory. Not initialized. void *malloc(size_t size);
free
void free(void *ptr);
calloc
// 为一个num个元素的数组分配内存。每一个有size字节,初始化为0。 void *calloc(size_t num, size_t size)
realloc
// 将ptr指向的block的大小改为size。 // 可能会将这个block移动到一个新的地址。 // block的内容会保留新的大小和旧的大小中较小者。 // 如果新的大小更大,那么多出来的是未定义的。 // 如果ptr==NULL,等价于malloc void *realloc(void *ptr, size_t size);
atoi
int atoi(const char *str);
atof
double atof(const char *str);
atol
long int atol(const char *str);
strtol
// base是进制 long int strtol(const char *str, char **endptr, int base)
Example:
char str[] = "2001 60cf2d -1100110010 0x6fff"; long int a,b,c,d; char *sp; a = strtol(str, &sp, 10); b = strtol(sp, &sp, 16); c = strtol(sp, &sp, 2); d = strtol(sp, NULL, 0);
strtoul
unsigned long int strtoul(const char *str, char **endptr, int base);
strtod
double strtod(const char *str, char **endptr);
printf
// Format: %[flags][width][.precision][length]specifier /** * specifier * d/i 有符号十进制整数 * u 无符号十进制整数 * o 无符号八进制 * x 无符号十六进制整数 * X 同上,但是X大写 * f/F 浮点数 小写/大写 * e/E 科学计数法 小写/大写 * g/G use the shortest representation: (%e or %f / %E or %F) * p pointer address */ /** * Flags * - 左对齐 * + 强制显示+-号 * (space) 如果没有符号位可写,加空格 * # (oxX)会打出(0,0x,0X), (aef)会打出小数点 */ /** * width * (number) number较大将显示的位数补空格。number小则无影响 * * 在...中给出 */ /** * .precision * (number) (ef)保留位数。s打印个数 * (.*) ...中给出 */ /** * length * l long * h short * U long long * z size_t */ int printf(const char *format, ...);
5.2 realpath
#include <limits.h> #include <stdlib.h> char *realpath(const char *path, char *resolved_path);
Resolve symbolic link, .
..
.
If resolved_path
is NULL, it will malloc
and return the pointer.
The caller is responsible to free
it.
On error, the return value is NULL
, and errno
is set.
But, it does not check if the file actually exists or not!
5.3 sys/time.h
gettimeofday
// tzp = NULL // 返回从1970.1.1 00:00 UTC 到现在的秒数 int gettimeofday(struct timeval *tp, void *tzp); struct timeval { __time_t tv_sec; __suseconds_t tv_usec; }
6 strings.h
strcasecmp
// 忽略大小写。比较所有字节。 // 返回:s1>s2: >0 // s1=s2: =0 // s1<s2: <0 int strcasecmp(const char *s1, const char *s2);
strncasecmp
// 比较前n个字节 int strncasecmp(const char *s1, const char *s2, size_t n);
strlen
// ssize_t: signed int(POSIX) // size_t: unsigned int size_t strlen(const char *str);
7 unistd
getopt
/* * optstring: * 单个字符 => 选项 * 单字符: => 选项后须跟参数,且可隔空格可不隔 * 单字符:: => 选项后须跟参数,必须紧跟,无空格 * * 全局变量 * char *optarg => 指向选项参数的指针 * int optind => 再次调用时,从此处开始分析 * int optopt => 最后一个已知选项 */ int getopt(int argc, char* const argv[], const char *optstring);
example
#include <unistd.h> int bflag, ch, fd; bflag = 0; while ((ch = getopt(argc, argv, "bf:")) != -1) { switch (ch) { case 'b': bflag = 1; break; case 'f': if ((fd = open(optarg, O_RDONLY, 0)) < 0) { (void)fprintf(stderr, "myname: %s: %s\n", optarg, strerror(errno)); exit(1); } break; case '?': default: usage(); } } // updates argc and argv to point to the rest of the arguments (- options skipped). argc -= optind; argv += optind;
7.1 readlink
Follow symbolic link of path
, get result into buf
.
Will fail (return -1) if path
is not a symbolic link.
Do not use this function to get the absolute path.
Use realpath
instead.
However, the shell utility works, realpath -f ./some/path
will produce the absolute path.
But realpath
can also do this, so do NOT use this.
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize);
Usage
if ((len = readlink("/modules/pass1", buf, sizeof(buf)-1)) != -1) { buf[len] = '\0'; }