C/C++字符串处理相关总结

总览

< cctype >头文件的函数

< cctype >头文件中声明了一系列用于字符处理的函数
http://www.cplusplus.com/reference/cctype/

判断字符是否属于某一类

函数功能
int isalnum ( int c );检查字符是否为字母或数字
int isalpha ( int c );检查字符是否为字母
int isblank ( int c );检查字符是否为空白符(’ ’ ‘\t’)
int iscntrl ( int c );检查字符是否为控制字符
int isdigit ( int c );检查字符是否为十进制数字
int isgraph ( int c );检查字符是否具有图形表示
int islower ( int c );检查字符是否为小写字母
int isprint ( int c );检查字符是否可打印
int ispunct ( int c );检查字符是否为标点符号
int isspace ( int c );检查字符是否为white-space (’ ’ ‘\t’ ‘\n’ ‘\v’ ‘\f’ ‘\r’)
int isupper ( int c );检查字符是否为大写字母
int isxdigit ( int c );检查字符是否为十六进制数字

字符转换函数

函数功能
int tolower ( int c );将大写字母转换为小写
int toupper ( int c );将小写字母转换为大写

头文件内< cstring >的函数

<cstring>

http://www.cplusplus.com/reference/string/

Copying:
memcpyCopy block of memory (function )
memmoveMove block of memory (function )
strcpyCopy string (function )
strncpyCopy characters from string (function )

strcpy把 src 所指向的字符串复制到 dest。

char *strcpy(char *dest, const char *src);
[参数]
dest -- 指向用于存储复制内容的目标数组。
src -- 要复制的字符串。
[返回值]
该函数返回一个指向最终的目标字符串 dest 的指针。
Concatenation:
strcatConcatenate strings (function )
strncatAppend characters from string (function )
Comparison:
memcmpCompare two blocks of memory (function )
strcmpCompare two strings (function )
strcollCompare two strings using locale (function )
strncmpCompare characters of two strings (function )
strxfrmTransform string using locale (function )
Searching:
memchrLocate character in block of memory (function )
strchrLocate first occurrence of character in string (function )
strcspnGet span until character in string (function )
strpbrkLocate characters in string (function )
strrchrLocate last occurrence of character in string (function )
strspnGet span of character set in string (function )
strstrLocate substring (function )
strtokSplit string into tokens (function )
Other:
memsetFill block of memory (function )
strerrorGet pointer to error message string (function )
strlenGet string length (function )

strlen()函数用来计算字符串的长度,其原型为:

unsigned int strlen (char *s);
【参数说明】s为指定的字符串。
strlen()用来计算指定的字符串s 的长度,不包括结束字符"\0"。
【返回值】返回字符串s 的字符数。

头文件< string >中的函数

<string>

http://www.cplusplus.com/reference/string/

Convert from strings
stoiConvert string to integer (function template )
stolConvert string to long int (function template )
stoulConvert string to unsigned integer (function template )
stollConvert string to long long (function template )
stoullConvert string to unsigned long long (function template )
stofConvert string to float (function template )
stodConvert string to double (function template )
stoldConvert string to long double (function template )
Convert to strings
to_stringConvert numerical value to string (function )
to_wstringConvert numerical value to wide string (function )

为什么size_t重要?

为什么size_t重要?

ASCII字符与转义字符

http://c.biancheng.net/cpp/html/2890.html
转义字符以\或者\x开头,以\开头表示后跟八进制形式的编码值,以\x开头表示后跟十六进制形式的编码值。对于转义字符来说,只能使用八进制或者十六进制。

字符 1、2、3、a、b、c 对应的 ASCII 码的八进制形式分别是 61、62、63、141、142、143,十六进制形式分别是 31、32、33、61、62、63。下面的例子演示了转义字符的用法:
转义字符既可以用于单个字符,也可以用于字符串,并且一个字符串中可以同时使用八进制形式和十六进制形式。
在这里插入图片描述
常见的转义字符如下

转义字符意义ASCII码值(十进制)
\a响铃(BEL)007
\b退格(BS) ,将当前位置移到前一列008
\f换页(FF),将当前位置移到下页开头012
\n换行(LF) ,将当前位置移到下一行开头010
\r回车(CR) ,将当前位置移到本行开头013
\t水平制表(HT)009
\v垂直制表(VT)011
单引号039
"双引号034
\反斜杠092

单引号、双引号、反斜杠是特殊的字符,不能直接表示:

  • 单引号是字符类型的开头和结尾,要使用 \’ 表示,也即’ \’ ';
  • 双引号是字符串的开头和结尾,要使用 \" 表示,也即" abc\"123 ";
  • 反斜杠是转义字符的开头,要使用\\表示,也即’\\’,或者"abc\\123"。

读入一行数据

第一种:在头文件<istream>中,是iostream类的成员函数。
第二种:在头文件<string>中,是普通函数。

第一种: 在中的getline()函数有两种重载形式:

istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );

作用是: 从istream中读取至多n个字符(包含结束标记符)保存在s对应的数组中。即使还没读够n个字符,

如果遇到delim 或 字数达到限制,则读取终止,delim都不会被保存进s对应的数组中。

第二种: 在中的getline函数有四种重载形式:

istream& getline (istream&  is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream&  is, string& str);
istream& getline (istream&& is, string& str);

用法和上第一种类似,但是读取的istream是作为参数is传进函数的。读取的字符串保存在string类型的str中。

函数的变量:
is :表示一个输入流,例如 cin。
str :string类型的引用,用来存储输入流中的流信息。
delim :char类型的变量,所设置的截断字符;在不自定义设置的情况下,遇到’\n’,则终止输入。

  • stringstream
    c++ stringstream
    库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。

1.stringstream::str(); 返回带有流当前内容副本的字符串对象

2.stringstream::str (const string& s); 将s设置为流的内容,并丢弃所有先前的内容。

3.stringstream s; s.str(""); 清空流

4.实现任意类型的转换
示例

#include<iostream>
#include<string>
#include<sstream>
using namespace std;


template<typename out_type, typename in_value>
out_type convert(const in_value & t){
    stringstream stream;
    stream<<t;
    out_type result;
    stream>>result;
    return result;
}


int main(){
    string s = "1 23 # 4";
    stringstream ss;
    ss<<s;
    while(ss>>s){
        cout<<s<<endl;
        int val = convert<int,string>(s);
        cout<<val<<endl;
    }
    return 0;
}

在这里插入图片描述

清空字符串区域

  • memset(): 复制字符 value(一个无符号字符)到参数 ptr 所指向的字符串的前 num 个字符; value为要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
    http://www.cplusplus.com/reference/cstring/

头文件

<cstring>
void * memset ( void * ptr, int value, size_t num );

Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).
char* m_buf = new char[10];    
memset(m_buf, '\0', 10);
  • bzero():置字节字符串s的前n个字节为零且包括‘\0’。
    头文件
#include <string.h>
extern void bzero(void *s, int n);
参数说明:s 要置零的数据的起始地址; n 要置零的数据字节个数。

说明:bzero无返回值,并且使用string.h头文件,string.h曾经是posix标准的一部分,但是在POSIX.1-2001标准里面,这些函数被标记为了遗留函数而不推荐使用。在POSIX.1-2008标准里已经没有这些函数了。推荐使用memset替代bzero。

复制字符串区域

  • strcpy():把 src 所指向的字符串复制到 dest。需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。
char *strcpy(char *dest, const char *src)
  • strncpy():把 src 所指向的字符串复制到 dest,最多复制 n 个字符。当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。
char *strncpy(char *dest, const char *src, size_t n);

搜索字符串相关

  • strrchr:
char *strrchr(const char *str, int c)

函数说明:在参数 str 所指向的字符串中搜索最后一次出现字符 c(一个无符号字符)的位置

strpbrk():

char *strpbrk(const char *str1, const char *str2)

检索字符串 str1 中第一个匹配字符串 str2 中字符的字符,不包含空结束字符。
也就是说,依次检验字符串 str1 中的字符,当被检验字符在字符串 str2 中也包含时,
则停止检验,并返回该字符位置。

示例来自https://www.runoob.com/cprogramming/c-function-strpbrk.html

#include <stdio.h>
#include <string.h>
 
int main ()
{
   const char str1[] = "abcde2fghi3jk4l";
   const char str2[] = "34";
   char *ret;
 
   ret = strpbrk(str1, str2);
   if(ret) 
   {
      printf("第一个匹配的字符是: %c\n", *ret);
   }
   else 
   {
      printf("未找到字符");
   }
   
   return(0);
}
  • strspn()
size_t strspn(const char *str1, const char *str2)

检索字符串 str1 中第一个不在字符串 str2 中出现的字符下标

字符串连接

  • strcat(): 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾
char *strcat(char *dest, const char *src);

参数
dest -- 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
src -- 指向要追加的字符串,该字符串不会覆盖目标字符串。

返回值
该函数返回一个指向最终的目标字符串 dest 的指针。

字符串分割

在C++中没有直接对应的split函数,字符串分割可借助以下方法实现:
1、借助strtok函数
http://www.cplusplus.com/reference/cstring/strtok/
头文件

<cstring>

函数原型:

char * strtok ( char * str, const char * delimiters );

函数功能:以delim为分隔符分割字符串str
参数说明:str:要分隔的字符串;delim:分隔符

描述:strtok()用来将字符串分割成一个个片段,参数s指向将要被分隔的字符串,参数delim则为分隔字符串,当strtok()在参数s的字符串中发现到参数delim的分隔字符时,则会将该字符改为’\0’字符,直到找遍整个字符串, 返回指向下一个标记串,当没有标记串时则返回空字符NULL。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回被分隔片段的指针

注意:

  • strtok是一个线程不安全的函数,因为它使用了静态分配的空间来存储被分割的字符串位置,线程安全的函数叫strtok_r。

1.strtok函数分割char*类型的字符串

#include <iostream>
#include<cstring>

using namespace std;
 
int main() {
	char s[] ="192.,*168.0.,*8...";// "my  name is lmm";
	char *p;
	const char *delim = ".,*";
	p = strtok(s, delim);
	while(p) {
		cout << p << endl;
		p = strtok(NULL, delim);
	}
    system("pause");
	return 0;
}

在这里插入图片描述

  1. 借助strtok分割string类型的字符串,将结果保存在vector中
#include <iostream>
#include<vector>
#include<cstring>
using namespace std;

vector<string> split(const string& str,const string& delim){
    if(str=="")    return {};
    vector<string> res;
    //先将要切割的字符串从string类型转换为char*类型
    char* cstr=new char[str.length()+1];
    strcpy(cstr,str.c_str());
    char* cdelim=new char[delim.length()+1];
    strcpy(cdelim,delim.c_str());

    char* p=strtok(cstr,cdelim);
    while(p){
        string s=p;
        res.push_back(s);
        p=strtok(NULL,cdelim);
    }
    delete cstr;
    delete cdelim;

    return res;
}

int main() {
    string str="192.,*168.0.,*8...";
    string delim=".,*";
    vector<string> res=split(str,delim);
    for(auto&i:res)
        cout<<i<<endl;
    system("pause");
	return 0;
}

在这里插入图片描述

字符串比较

  • strcmp
    头文件
<string.h>
int strcmp(const char *str1, const char *str2);
参数
str1 -- 要进行比较的第一个字符串。
str2 -- 要进行比较的第二个字符串。

返回值
该函数返回值如下:
如果返回值小于 0,则表示 str1 小于 str2。
如果返回值大于 0,则表示 str1 大于 str2。
如果返回值等于 0,则表示 str1 等于 str2。
  • strcasecmp

头文件:

#include <string.h>
函数说明:strcasecmp()用来比较参数s1 和s2 字符串,比较时会自动忽略大小写的差异。
int strcasecmp (const char *s1, const char *s2);

返回值:若参数s1 和s2 字符串相同则返回0。s1 长度大于s2 长度则返回大于0 的值,s1 长度若小于s2 长度则返回小于0 的值。

字符串转整型/浮点型

字符串到数字的转换可以通过 stoX() 系列函数来执行。该系列函数的成员可以将字符串转换为 int、long、float 和 double 类型的数字。具体语法如下所示:
1.头文件< string >中

<string>
int stoi(const strings str, size_t* pos = 0, int base = 10)
long stol(const strings str, size_t* pos = 0, int base = 10)
float stof(const strings str, size_t* pos = 0)
double stod(const strings str, size_t* pos = 0)

第一个形参 str 是一个字符串(例如 “-342” 或 “3.48” 等),它将被转换为恰当的数字形式。这些函数可以将 str 可能的最长前缀转换为数字,并返回一个整数地址 pos,pos 中保存了 str 无法被转换的第一个字符的索引。类型 size_t 是在标准库中定义的,常用于表示无符号整数的大小或数组、矢量、字符串中的一个索引。

例如,如果试图转换字符串 “-34iseven”,则将成功返回整数 -34,而无法转换的第一个字符的位置 pos 则被设置为 3。base 形参仅适用于整数转换,指示用于转换的进制。pos 和 base 形参都是可选的,所以它们可以被忽略。如果 pos 被忽略,则不会存储停止字符的索引。如果 base 被忽略,则默认为十进制。如果字符串 str 包含一个无效值,例如 “is-34 even?”,则不会进行转换,函数将抛出一个 invalid_argument 异常。

2.头文件< cstdlib >中

<cstdlib>

http://www.cplusplus.com/reference/cstdlib/

函数功能
atofConvert string to double (function )
atoiConvert string to integer (function )
atolConvert string to long integer (function )
atollConvert string to long long integer (function )
strtodConvert string to double (function )
strtofConvert string to float (function )
strtolConvert string to long integer (function )
strtoldConvert string to long double (function )
strtollConvert string to long long integer (function )
strtoulConvert string to unsigned long integer (function )
strtoullConvert string to unsigned long long integer (function )

整型/浮点型转字符串

来自http://c.biancheng.net/view/1527.html

C++ 11 提供了若干 to_string(T value) 函数来将 T 类型的数字值转换为字符串形式。
以下是几个 to_string() 函数的列表:

1.头文件< string >中

<string>

http://www.cplusplus.com/reference/string/to_string/?kw=to_string

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

2.头文件< stdio.h >中

  • sprintf
#include <stdio.h>

sprintf()函数用于将格式化的数据写入字符串,其原型为:

int sprintf(char *str, char * format [, argument, ...]);
【参数】str为要写入的字符串;format为格式化字符串,与printf()函数相同;argument为变量。

除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数--格式化字符串--上。
printf()sprintf()都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。

【返回值】成功则返回参数str 字符串长度,失败则返回-1,错误原因存于errno 中。

常见的format格式:
    %% 印出百分比符号,不转换。
  %c 整数转成对应的 ASCII 字元。
  %d 整数转成十进位。
  %f 倍精确度数字转成浮点数。
  %o 整数转成八进位。
  %s 整数转成字符串。
  %x 整数转成小写十六进位。
  %X 整数转成大写十六进位。
  %n sscanf(str, "%d%n", &dig, &n)%n表示一共转换了多少位的字符
  • snprintf

注意:C语言对数组进行操作时并不检测数组的长度,如果str的长度不够,上面的sprintf()很容易造成缓冲区溢出,带来意想不到的后果,黑客经常利用这个弱点攻击看上去安全的系统。
使用snprintf()来代替sprintf()将能够很好的解决这个问题。

功能:设将可变参数(...)按照 format 格式化成字符串,并将字符串复制到 str 中,size 为要写入的字符的最大数目,超过 size 会被截断。

int snprintf ( char * str, size_t size, const char * format, ... );

参数
str -- 目标字符串。
size -- 拷贝字节数(Bytes)。
format -- 格式化成字符串。
... -- 可变参数。

返回值
(1) 如果格式化后的字符串长度小于等于 size,则会把字符串全部复制到 str 中,并给其后添加一个字符串结束符 \0(2) 如果格式化后的字符串长度大于 size,超过 size 的部分会被截断,只将其中的 (size-1) 个字符复制到 str 中,并给其后添加一个字符串结束符 \0,返回值为欲写入的字符串长度。

示例

#include <stdio.h>
 
int main()
{
    char buffer[50];
    char* s = "runoobcom";
 
    // 读取字符串并存储在 buffer 中
    int j = snprintf(buffer, 6, "%s\n", s);
 
    // 输出 buffer及字符数
    printf("string:\n%s\ncharacter count = %d\n", buffer, j);
 
    return 0;
}
  • int vsprintf(char *str, const char *format, va_list arg) 使用参数列表发送格式化输出到字符串。
    头文件
#include <stdarg.h>
#include <stdio.h>
int vsprintf(char *str, const char *format, va_list arg)

str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。
format -- 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是 %[flags][width][.precision][length]specifier,

具体的见https://www.runoob.com/cprogramming/c-function-vsprintf.html

int vsnprintf( char* buf,size_t count,const char* format,va_list arg );

用法类似于vsprintf,不过加了count的限制,防止了内存溢出(count为str所指的存储空间的大小)。

返回值:执行成功,返回最终生成字符串的长度,若生成字符串的长度大于size,
则将字符串的前size个字符复制到str,同时将原串的长度返回(不包含终止符);
执行失败,返回负值,并置errno

va_start(),va_end()函数应用

va_list ap; //声明一个变量来转换参数列表
va_start(ap,format); //初始化变量
va_end(ap); //结束变量列表,和va_start成对使用
可以根据va_arg(ap,type)取出参数

示例

/* vsnprintf example */
#include <stdio.h>
#include <stdarg.h>

void PrintFError ( const char * format, ... )
{
  char buffer[256];
  va_list args;
  va_start (args, format);
  vsnprintf (buffer,256,format, args);
  perror (buffer);
  va_end (args);
}

int main ()
{
   FILE * pFile;
   char szFileName[]="myfile.txt";

   pFile = fopen (szFileName,"r");
   if (pFile == NULL)
     //可变参数...为空也可以
     //PrintFError("Error opening");这样也可以调用成功的。
     PrintFError ("Error opening '%s'",szFileName);
   else
   {
     // file successfully open
     fclose (pFile);
   }
   return 0;
}

stat函数讲解

头文件:

 #include <sys/stat.h>
 #include <unistd.h>
int stat(const char *file_name, struct stat *buf);

函数说明:    通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值:      执行成功则返回0,失败返回-1,错误代码存于errno

错误代码:
    ENOENT         参数file_name指定的文件不存在
    ENOTDIR        路径中的目录存在但却非真正的目录
    ELOOP          欲打开的文件有过多符号连接问题,上限为16符号连接
    EFAULT         参数buf为无效指针,指向无法存在的内存空间
    EACCESS        存取文件时被拒绝
    ENOMEM         核心内存不足
    ENAMETOOLONG   参数file_name的路径名称太长

stat结构体

struct stat {
    dev_t         st_dev;       //文件的设备编号
    ino_t         st_ino;       //节点
    mode_t        st_mode;      //文件的类型和存取的权限
    nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
    uid_t         st_uid;       //用户ID
    gid_t         st_gid;       //组ID
    dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
    off_t         st_size;      //文件字节数(文件大小)
    unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
    unsigned long st_blocks;    //块数
    time_t        st_atime;     //最后一次访问时间
    time_t        st_mtime;     //最后一次修改时间
    time_t        st_ctime;     //最后一次改变时间(指属性)
};

先前所描述的st_mode 则定义了下列数种情况:
    S_IFMT   0170000    文件类型的位遮罩
    S_IFSOCK 0140000    scoket
    S_IFLNK 0120000     符号连接
    S_IFREG 0100000     一般文件
    S_IFBLK 0060000     区块装置
    S_IFDIR 0040000     目录
    S_IFCHR 0020000     字符装置
    S_IFIFO 0010000     先进先出

    S_ISUID 04000     文件的(set user-id on execution)位
    S_ISGID 02000     文件的(set group-id on execution)位
    S_ISVTX 01000     文件的sticky位

    S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
    S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
    S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限

    S_IRGRP 00040             用户组具可读取权限
    S_IWGRP 00020             用户组具可写入权限
    S_IXGRP 00010             用户组具可执行权限

    S_IROTH 00004             其他用户具可读取权限
    S_IWOTH 00002             其他用户具可写入权限
    S_IXOTH 00001             其他用户具可执行权限

上述的文件类型在POSIX中定义了检查这些类型的宏定义:
    S_ISLNK (st_mode)    判断是否为符号连接
    S_ISREG (st_mode)    是否为一般文件
    S_ISDIR (st_mode)    是否为目录
    S_ISCHR (st_mode)    是否为字符装置文件
    S_ISBLK (s3e)        是否为先进先出
    S_ISSOCK (st_mode)   是否为socket

若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值