标准函数库

数组

拷贝数据
void *memcpy(void *dest, const void *src, size_t count); // => wmemcpy

memcpysrc拷贝count字节数据到destwmemcpy则拷贝count个宽字符的数据。如果源和目的区域有重叠,则该函数的行为未定义。

注意:应该保证目的缓存应该大于或等于源缓存。

void *memmove(void *dest,const void *src, size_t count); 
// => wmemmove、memmove_s、wmemmove_s

srcdest拷贝count字节(memmove)或字符(wmemmove)。如果源和目的区域有重叠,则该函数能保证覆盖区域的数据被覆盖之前被正确拷贝。

注意:应该保证目的缓存应该大于或等于源缓存。

设置数据

memset

比较

memcmp

C字符串

char型字符串==存储变长字符编码==(Linux平台为UTF-8,Windows平台为GBK),以单字节“null”结尾;wchar_t存储定长字符编码(UTF-16),以两个“null”结尾。

wchar_t字符串的处理函数以wcs开头,对应char字符串以str开头的函数。

char str[5] = {'T', 'h', 'i', 's', 0};  // string as array

当使用字符串字面值初始化时,对应的字符串是不能修改的,因此将其声明为常量。

const char str[] = "this is a string";
const char* ptr = "this is a string";

属性

size_t strlen(const char *s);	  // => wcslen

计算字符串长度,遇到'\0'结束,==长度以字节计数==;如果是中文,则一般一个中文字符占3字节。

拼接

char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n);

将字符串src连接到dest的尾部。从dest\0开始。strncatstrcat的区别在:strncat最多使用srcn个字节;如果src的长度大于或等于n,则strncatsrc字符串不需要是null结尾。

strlen()strcat()是两个比较耗时的操作。在程序中应该少使用。

比较

int strcmp(const *s1,const *s2);
int strncmp(const char *s1, const char *s2, size_t n);
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *s1, const char *s2, size_t n);

比较s1s2strncmp只比较最多n个字符。strcasecmp忽略大小写。

  • s1 = s2的时候返回值 =0;
  • s1 < s2的时候返回至 <0;
  • s1 > s2的时候返回值 >0;

查找

char *strchr(const char *s, char c);
char *strrchr(const char *s, int c);
char *strchrnul(const char *s, int c);

strchr返回s中首次出现c的位置的指针,strrchr返回最后出现c的位置的指针。如果s中不存在c则返回NULLstrchrnulstrchr类似,只是在找不到c的时候,返回字符串的null位置指针,而不是NULL

char *strstr(const char *haystack, const char *needle);
char *strcasestr(const char *haystack, const char *needle);

返回haystackneedle字符串首次出现的位置的指针(不比较结束符null)。若果没找到则返回NULLstrcasestr在查找时忽略字符串的大小写。

复制

char *strcpy(char *dest, const char *src);    // => wcscpy,wcscpy_s
char *strncpy(char *dest, const char *src, size_t n);  // => wcscat,wcscat_s

拷贝src指向的字符串到dest指向的缓冲区。strncpy则最多拷贝n个字符,如果前n个字符没有以null结束,则目标字符串也不会以null结束。

类型转换

#include <cstdlib>
int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);

将字符串转换成intlonglong long型整数。atoi()会扫描参数nptr字符串,跳过前面的空格,直到遇上数字或者正负号才开始装换,而再遇到非数字或者字符串结束时停止转换。atoi不会检测错误。

double atof(const char *nptr);

将字符串转换为浮点数。atof不会检测错误。

long int strtol(const char *nptr, char **endptr, int base);
long long int strtoll(const char *nptr, char **endptr, int base);

strtol根据base的值就将nptr指向的字符串转换为整数。base的取值范围为2~36,或为0。 字符串可以在开头包含任意数量的空格,空格之后可以包含“+”或“-”。如果base = 0,若字符串包含前缀“0x”,字符串字符串将按照16进制解析;若字符串包含前缀“0”,字符串字符串将按照8进制解析;其他情况则按10进制解析。解析停止于首个非法字符。

如果endptr不是NULL,则strtol将把首个非法字符的地址存储在*endptr中。如果nptr中没有数字,则*endptr=nptr并返回0,如果nptr!=NULL*endnptr=NULL,则全部是合法字符。

strtollstrtol类似,只是返回值的类型为long long int。如果发生下溢出,则strtol返回LONG_MIN;如果发生上溢出,则strtol返回LONG_MAX。两种情况下,errno被设置为ERANGEstrtoll也是类似,只是返回值为LLONG_MINLLONG_MAX

unsigned long int strtoul(const char *nptr, char **endptr, int base);
unsigned long long int strtoull(const char *nptr, char **endptr, int base);

strtoul根据base的值将nptr指向的字符串转换为无符号整数,转换规则与strtol类似。

double strtod(const char *nptr, char **endptr);
float strtof(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);

nptr指向的字符串转换为浮点数。

格式化

int sprintf(char *buf, char *format,arg_list);
int snprintf(char *restrict buf, size_t n, const char *restrict format,...);

sprintf()是一个功能强大的函数。跟printf(char *format,arg_list)的功能类似。不过,printf()是将格式化的字符输出到屏幕,而sprintf()则是将格式化的字符放入到buf中。这个函数对操作缓冲区buf,并对其内容加以格式带来了极大的方便。

snprintf()最多从源串format中拷贝n-1个字符到目标串buf中,然后再在后面加一个'\0'.如果目标串的大小为n的话,将不会溢出。snprintf()如果成功则返回存入数组的字符数,若错误则返回负值。

int sscanf(string str, string fmt, mixed var1, mixed var2 ... );
int scanf(const char *format [,argument]... );  

从一个字符串中读进与指定格式相符的数据。sscanfscanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。其中,format可以是一个或多个

{%[*][width][{h|l|I64|L}]type|' '|'\t'|'\n'|非%符号}

格式化输入
char buf[512];
sscanf("123456 ", "%s", buf);
sscanf("123456 ", "%4s", buf);  // 取最大长度为4字节的字符串

正则匹配:sscanf%[]类似于一个正则表达式,但却没有正则表达式强大,所以如果对于比较复杂的字符串处理,建议使用正则表达式。

sscanf("123456 abcdedf", "%[^ ]", buf); // 取遇到空格为止字符串
sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf); //仅包含指定字符集的字符串
sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);

给定一个字符串iios/12DDWDFF@122,获取 /@ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf

sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);
sscanf(“hello, world”, "%*s%s", buf);

%*s表示第一个匹配到的%s被过滤掉,即'hello'被过滤了;如果没有空格则结果为NULL。

其他方法

strace       strcspn      strings      strdup       strip        strpbrk 
strdupa      strtok       strtouq      strerror     strtok_r     strverscmp
strerror_r   strsep       strxfrm      strchrnul    strfmon      strsignal    
strfry       strspn       strcoll      strndup      string       strndupa       

时间

时间格式化
size_t strftime(
   char *strDest,
   size_t maxsize,
   const char *format,
   const struct tm *timeptr
);

format用于声明格式化字符串

时间字符串解析
strptime

系统调用

文件系统

#include <stdio.h>
int rename( const char *oldfname, const char *newfname ); // 更改文件名

系统接口

system解释执行一条命令。函数将命令传递给命令环境(Shell),如果输入命令为空,则system函数检查命令环境是否存在。在使用system函数前,必须显式调用刷新流(调用fflush_flushall)或者关闭流。

#include <stdlib.h>
int system(const char *command );
int _wsystem(const wchar_t *command);

_wsystem是宽字符版本的system函数。_tsystem则根据程序中是否定义了_UNICODE来确定使用的函数。

如果输入命令为空,而命令解释器为找到,则返回0并且将errno设为``ENOENT,否则返回一个非零值;如果输入命令不为空,而命令解释器可以找到,则函数返回值就是命令解释器返回的值。如果返回-1,表明发生了错误,errno`设置为以下值:

  • E2BIG
  • ENOENT 未能找到解释器
  • ENOEXEC 解释器的格式无效,不能执行
  • ENOMEM 内存不足。