字符串常用操作
1.前言
在头文件cstring中定义了22个不同的操控c风格的字符串和数组函数。
2.Copying functions
1.memcpy:copy block of memory
Example:
//拷贝内存块
#include <iostream>
#include <cstring>
struct
{
char name[10];
int age;
}person,person_copy;
int main()
{
char my_name[] = "Jimi.Hso";
//copy string
memcpy(person.name,my_name,sizeof(my_name));
person.age = 18;
//copy struct
memcpy(&person_copy,&person,sizeof(person));
std::cout << "name:" << person_copy.name << "age:" << person_copy.age << std::endl;
return 0;
}
2.memmove:move block of memory.memmove is a safer approach than memcpy
Example:
//移动内存块
#include <iostream>
#include <cstring>
int main()
{
char arr[] = "HelloWorld";
memmove(arr + 10,arr,5);
puts(arr); //HelloWorldHello
return 0;
}
3.strcpy:copy string.Note that the strcpy function copies the c string pointed by source into the array pointed by destination,including the terminating null character(and stop at that point)
Example:
//拷贝字符串时,会将源端的中止字符拷贝过来,将目的端的终止符覆盖
#include <iostream>
#include <cstring>
int main()
{
char arr[11] = "Hello";
strcpy(arr + 5,"World");
std::cout << arr << std::endl; //HelloWorld
return 0;
}
4.strncpy:copy characters from string
Example
//拷贝字符
#include <iostream>
#include <cstring>
int main()
{
const char* str = "World";
char * ptr = new char[strlen(str) + 1];
strncpy(ptr,str,strlen(str));
ptr[5] = '\0';
std::cout << ptr << std::endl;
delete[]ptr;
return 0;
}
3.Concatenation
1.strcat:concatenate strings。目标端的一段连续空间(数组)应当足够容纳源端的字符串。
2.strncat:append characters from string
4.Comparison
1.memcmp:compare two blocks of memory.Note that,unlike strcmp,the function dose not stop comparing after finding a null character.
Example:
//比较内存块,在用memcmp函数时,比较的字节数最好不要超过两个内存块中较大的那个的长度
#include <iostream>
#include <cstring>
int main()
{
char buffer1[] = "Hello";
char buffer2[] = "Hello";
int ret = memcmp(buffer1,buffer2,sizeof(buffer2) + 1); //遇到'\0'继续比较,这里ret为1
//int ret = strcmp(buffer1,buffer2);
if(ret < 0)
{
std::cout << buffer1 << "is less than " << buffer2 << std::endl;
}
else if(ret > 0)
{
std::cout << buffer1 << "is greater than " << buffer2 << std::endl;
}
else
{
std::cout << buffer1 << "is the same as " << buffer2 << std::endl;
}
return 0;
}
2.strcmp:compare two strings
3.strcoll:compare two strings using locale.Note that the behavior of this function depends on the LC_COLLATE category of the selected C locale.locale是啥具体参见locale.h头文件的内容
4.strncmp:compare characters of two strings
5.strxfrm:transform string using locale.Transfroms the C string pointed by source according the curent locale and copies the first num characters of the transformed string to destination,returning its(the tansformed string) length总之就是根据当前的locale转化源端字符串,再拷贝源端的num个字符到目的端
5.Searching
1.memchr:locate character in block of memory
Example:
//在内存块中字符定位,此函数返回第一次指针指向第一次出现待查找字符的位置,没找到就返回nullptr
#include <iostream>
#include <cstring>
int main()
{
char str[] = "HelloWorld,aAA";
char* ptr = (char*)memchr(str,'a',strlen(str));
if(ptr != nullptr)
{
*ptr = 'A'; //找到a第一次出现的位置并修改a
}
std::cout << str << std::endl; //HelloWorld,AAA
return 0;
}
2.strchr:locate first occurrence of character in string..定位给定字符第一次在字符串中出现的位置,如果给定的字符没有找到就返回空指针。对于此函数的第二参数,虽然传递的是一个整形数,内部会将它转化为字符型来比较。
Example:
//定位一个字符在字符串中第一次出现的位置
#include <iostream>
#include <cstring>
int main()
{
char str[] = "HelloWorld,aaaahhhaaa";
char * ptr = strchr(str,'a');
while(ptr)
{
*ptr = 'A';
ptr = strchr(ptr + 1,'a');
}
std::cout << str << std::endl; //HelloWorld,AAAAhhhAAA
return 0;
}
3.strcspn:get span(跨度) until character in string.Scans str1 for the first occurence of any of the characters that are part of str2,returning the number of characters of str1 read before this first occurence.
Example:
#include <iostream>
#include <cstring>
int main()
{
const char * str1 = "HelloWorld";
const char * str2 = "World";
int num = strcspn(str1,str2);
std::cout << num << std::endl;
//为2,str2中的一个字符在str1中最先出现的是l,在此之前str1已经查找了两个字符
return 0;
}
4.strpbrk:locate characters in string。Returns a pointer to the first occurrence in str1 of any of the characters that are part of str2,or a null pointer if there are no matches.在一个字符串中匹配定位另一个字符串的字符的位置,返回定位到的第一个字符在待查找字符串中的位置。
Example:
#include <iostream>
#include <cstring>
int main()
{
char str[] = "HelloWorld";
const char * match = "o";
char * ptr = strpbrk(str,match);
while(ptr)
{
*ptr = 'O';
ptr = strpbrk(ptr + 1,match);
}
puts(str); //将o替换为O.
return 0;
}
5.strrchr:locate last occurrence of character in string.与strchr雷同,只不过此函数定位给定字符在字符串中最后出现的位置。
6.strspn:get span of character set in string.返回str1中从首字符开始连续的包含在str2中的字符长度(不包含空字符),如果str1中的第一个字符都不包含在str2中就直接返回0,不继续searching.
#include <iostream>
#include <cstring>
int main()
{
const char * str1 = "Hello";
//const char * str2 = "Horld";
const char * str2 = "Horel";
int num = strspn(str1,str2);
//std::cout << num << std::endl; //第二个字符在str2中没有所以结果为1
std::cout << num << std::endl; //5
return 0;
}
7.strstr:locate substring.主串中匹配子串,返回指向主串中第一次出现子串的位置指针,找不到子串就返回空指针。
Example:
#include <iostream>
#include <cstring>
int main()
{
char mainString[] = "Hello,World.";
const char* subString = "World";
char * ptr = strstr(mainString,subString);
std::cout << ptr << std::endl; //World.
strncpy(ptr,"where",strlen(subString)); //Hello,where.
puts(mainString);
return 0;
}
8.strtok(token):split string into tokens(smaller strings).函数思想:To determine the beginning and the end of a token(其中一个 子串),the function scans from the starting location for the first character not contained in delimiters(which becomes the beginning of the token).And then scans starting from this beginning of the token for the first character contained in delimeters,which becomes the end of token.The scan also stops if the terminating null character is found. 其函数原型为:char * strtok(char * str,const char * delimeters)以某种规则(分隔符)将一个给定的字符串拆分成若干个小的字符串。
Example:
#include <iostream>
#include <cstring>
int main()
{
char str[] = "_this,a sample string.";
char * ptr = strtok(str,"_,. ");
while(ptr != nullptr)
{
std::cout << ptr << std::endl;
ptr = strtok(nullptr,"_,. ");
//这里strtok的第一个参数为nullptr的原因是:
//On a first call,the function expected a C string as first argument
//whose first character is used as the starting location to scan for
//tokens.In subsequent calls,the function expected a null pointer and
//uses the position right after the end of the last token as the new
//starting location for scanning.既然第二次调用strtok函数时会从第一次调用所取得
//的一个小字符串末尾开始扫描,那么第一个参数可以为空指针,只要扫描遇到中止空字符
//自然会中止扫描返回nullptr.
}
return 0;
}
//运行结果:
//this
//a
//sample
//string
6.Other
1.memset:fill block of memory.函数原型:void* memset(void * ptr,int value,size_t num).虽然第二个参数传过来的是一个整形数,但是这个填充内存块的函数使用的是整形数转型为unsigned char 的字符。
Example:
#include <iostream>
#include <cstring>
int main()
{
char arr[] = "hhhhh";
memset(arr,'H',strlen(arr));
puts(arr);
return 0;
}
2.strerror:get pointer of error message string函数原型:char *strerror(int errnum)函数的使用一般传递实参errno(标准库定义的宏)errno具体 参见cerrno/errno.h头文件内容。
#include <iostream>
#include <errno.h>
#include <cstring>
int main()
{
FILE * pFIle;
pFIle = fopen("Example.txt","r");
if(pFIle == nullptr)
{
std::cout << strerror(errno) << std::endl; //No such file or directory
}
return 0;
}
3.strlen:get string length 高效地(不是我们那种普通遍历一个一个字符)求一个c风格的字符串(不包括中止空字符)的长度。
7.总结
c函数库中提供了好多C风格字符串处理函数,这些只是在cstring头文件的一部分。也是我们能够常用的。C++中也提供了一个字符串类string,里面也有许多字符串处理函数。这一节只是简单的认识一下这些函数,如果深入的学习这些函数并用好,阅读源码是一种好的方式
reference:
http://ftp.gnu.org/gnu/glibc
http://www.cplusplus.com