strcpy,wcscpy的功能是复制字符串到目标,包括结尾的空字符。
char *strcpy( char *strDestination,const char *strSource);
wchar_t *wcscpy( wchar_t *strDestination,const wchar_t *strSource);
strcpy,wcscpy在复制前没有检查目标是否有足够的空间,所以有缓冲区溢出漏洞,应该使用更安全的版本:strcpy_s,wcscpy_s,它们会检查dest,src是否为空指针,或dest_size太小不足够存放src指向的字符串。
errno_t strcpy_s(char *dest, rsize_t dest_size, const char *src);
errno_t wcscpy_s(wchar_t *dest, rsize_t dest_size,const wchar_t *src);
int main()
{
char str[10]="123456789";
strcpy(str, "hello");
cout << str << endl;
strcpy(str, "hello world!!!!");//缓冲区溢出
cout << str << endl;
strcpy_s(str, "1234567890");//运行时错误
cout << str << endl;
strcpy_s(str, nullptr);//运行时错误
cout << str << endl;
system("pause");
}
strncpy类似strcpy,不过strncpy可以指定复制的字符数量。
char *strncpy(char *strDest,const char *strSource,size_t count);
wchar_t *wcsncpy(wchar_t *strDest,const wchar_t *strSource,size_t count);
errno_t strncpy_s(char *strDest,size_t numberOfElements,const char *strSource,size_t count);
errno_t wcsncpy_s(wchar_t *strDest,size_t numberOfElements,const wchar_t *strSource,size_t count);
int main()
{
char str[10]="123456789";
strncpy(str, "hello",2);
cout << str << endl;//he3456789
strncpy(str, "hello", 5);
cout << str << endl;//hello6789
wchar_t str1[10] = L"123456789";
wcsncpy(str1, L"hello", 2);
wcout << str<<endl;//he3456789
system("pause");
}
strcat,wcscat的功能是追加字符串到目标。
char *strcat(char *strDestination,const char *strSource);
wchar_t *wcscat(wchar_t *strDestination,const wchar_t *strSource);
strcat,wcscat在复制前没有检查目标是否有足够的空间,所以有缓冲区溢出漏洞,应该使用更安全的版本:strcat_s,wcscat_s,它们会检查strDestination,strSource是否为空指针,或numberOfElements太小不足够存放strSource指向的字符串。
errno_t strcat_s(char *strDestination,size_t numberOfElements,const char *strSource);
errno_t wcscat_s(wchar_t *strDestination,size_t numberOfElements,const wchar_t *strSource);
strlen,wcslen返回字符串中的字符数,不包括结尾的空字符。
size_t strlen(const char *str);
size_t wcslen(const wchar_t *str);
strlen,wcslen存在缓冲区溢出问题,应该使用更安全的版本:strnlen,strnlen_s,wcsnlen,wcsnlen_s,它们在指定字符数找不到空字符则返回指定字符数,strnlen_s,wcsnlen_s还检查字符串是否为空指针,是的话则返回0。
size_t strnlen(const char *str,size_t numberOfElements);
size_t strnlen_s(const char *str,size_t numberOfElements);
size_t wcsnlen(const wchar_t *str,size_t numberOfElements);
size_t wcsnlen_s(const wchar_t *str,size_t numberOfElements);
int main()
{
//cout << strnlen(nullptr,2) << endl;//触发异常
cout << strnlen("hello",2) << endl;//2
cout << strnlen("hello", 10) << endl;//5
cout << strnlen_s(nullptr, 2) << endl;//0
cout << wcsnlen(L"hello", 2) << endl;//2
cout << wcsnlen(L"hello", 10) << endl;//5
cout << wcsnlen_s(nullptr, 2) << endl;//0
system("pause");
}
strcmp,wcscmp的功能是比较两个字符串(区分大小写),相同则返回0,不区分大小写可以使用_stricmp,_wcsicmp(stricmp,wcsicmp是POSIX标准中的函数,_stricmp,_wcsicmp则是C++标准中的函数)。
int strcmp(const char *string1,const char *string2);
int wcscmp(const wchar_t *string1,const wchar_t *string2);
int _stricmp(const char *string1,const char *string2);
int _wcsicmp(const wchar_t *string1,const wchar_t *string2);
memcmp比较两个指针指向的内存的前count个字节,都相等则返回0。
int main()
{
char a1[] = { 'a','b','c' };
char a2[sizeof a1] = { 'a','b','d' };
cout << memcmp(a1, a2, sizeof a1) << endl;
char a3[] = { 'a','b','c' };
char a4[sizeof a3] = { 'a','b','c' };
cout << memcmp(a3, a4, sizeof a3) << endl;
system("pause");
}
memset将指针指向的内存的前count个字节都填充为指定值。
void *memset( void *dest, int ch, size_t count );
int main()
{
char str[10];
memset(str, 0x31323334, 10);
cout << str[0] << endl;//4
cout << str[1] << endl;//4
memset(str, 'a', 10);
cout << str[0] << endl;//a
cout << str[1] << endl;//a
system("pause");
}
memcpy从 src 所指向的内存复制 count 个字节 dest 所指向的内存,memcpy_s会检查dest或src是否为空指针(count不为0时)以及destSize是否小于count。
void *memcpy(void *dest,const void *src,size_t count);
errno_t memcpy_s(void *dest,size_t destSize,const void *src,size_t count);
int main()
{
char str[10];
memcpy(str, "123", 4);
cout << str << endl;
//memcpy(nullptr, "123", 4);//内存访问异常
//memcpy_s(nullptr, 10, "123", 4);//无效参数异常
//memcpy_s(nullptr, 10, nullptr, 4);//无效参数异常
//memcpy_s(str, 10, "123", 14);//无效参数异常
memcpy_s(str,10, "123", 4);
system("pause");
}
memmove和memcpy类似,不过memmove能确保dest和src指向的内存有重叠时拷贝的结果是正确的,memcpy则不一定。
int main()
{
//字符转换为小写
char c1 = 'A';
cout << static_cast<char>(tolower(c1)) << endl;//a
//字符转换为大写
c1 = 'b';
cout << static_cast<char>(toupper(c1)) << endl;//B
cout << endl;
//判断字符是否是小写字母,是的话返回非0值
cout << "判断字符是否是小写字母:" << endl;
cout << islower('a') << endl;//2
cout << islower('A') << endl;//0
cout << islower('/') << endl;//0
//判断字符是否是大写字母,是的话返回非0值
cout << "判断字符是否是大写字母:" << endl;
cout << isupper('a') << endl;//0
cout << isupper('A') << endl;//1
cout << isupper('/') << endl;//0
//判断字符是否是英文字母,是的话返回非0值
cout << "判断字符是否是英文字母:" << endl;
cout << isalpha('a') << endl;//2
cout << isalpha('1') << endl;//0
//判断字符是否是字母或数字,是的话返回非0值
cout << "判断字符是否是字母或数字:" << endl;
cout << isalnum('a') << endl;//2
cout << isalnum('1') << endl;//4
cout << isalnum('*') << endl;//0
//判断字符是否是数字,是的话返回非0值
cout << "判断字符是否是数字:" << endl;
cout << isdigit('a') << endl;//0
cout << isdigit('1') << endl;//4
cout << isdigit('*') << endl;//0
//判断字符是否是十六进制字符,是的话返回非0值
cout << "判断字符是否是十六进制字符:" << endl;
cout << isxdigit('a') << endl;//128
cout << isxdigit('1') << endl;//128
cout << isxdigit('X') << endl;//0
cout << isxdigit('z') << endl;//0
//判断字符是否拥有图形表示,是的话返回非0值
//即它是数字( 0123456789 )、大写字母( ABCDEFGHIJKLMNOPQRSTUVWXYZ )、小写字母( abcdefghijklmnopqrstuvwxyz )
//或标点字符( !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ),或任何指定于当前 C 本地环境的图形字符之一
cout << "判断字符是否拥有图形表示:" << endl;
cout << isgraph('a') << endl;//2
cout << isgraph('1') << endl;//4
cout << isgraph('\t') << endl;//0
cout << isgraph('\n') << endl;//0
//判断字符是否是控制字符,即0x00-0x1F 及 0x7F
cout << "判断字符是否是控制字符:" << endl;
cout << iscntrl('\x31') << endl;//0
cout << iscntrl('\n') << endl;//32
cout << iscntrl('\0') << endl;//32
cout << iscntrl('x') << endl;//0
//判断字符是否是空白字符,即空格( 0x20 )、换行( 0x0a )、回车( 0x0d )、水平制表符( 0x09 )或垂直制表符( 0x0b )之一
cout << "判断字符是否是空白字符:" << endl;
for (int i = 0; i <= UCHAR_MAX; i++)
if (isspace(i)) printf("0x%02x\n", i);
//判断字符是否是空格字符,即空格( 0x20 )与水平制表符( 0x09 )
cout << "判断字符是否是空格字符:" << endl;
for (int i = 0; i <= UCHAR_MAX; i++)
if (isblank(i)) printf("0x%02x\n", i);
system("pause");
}