字符串常用处理函数

#include <stdio.h>
#include <stdlib.h>

/* 函数名: substring
 * 功  能: 字符串任意截取
 * 用  法: char *substring(char *dst,char *src,int start,int end)
 * 返回值: 返回参数dest的字符串起始地址
 * 说  明: 从start到end截取,包括两端
 * 安全性:目标地址dest一定要足够大,不然可能会溢出,后果不堪设想。
 */
char *substring(char *dst,char *src,int start,int end)
{
	char *p=dst;    //等下要返回目标位置的首地址,所以不能直接用,地址会改变
	char *q_src=src;
	int length=strlen(src);
	q_src+=start;
	if(start<=end&&end<=length-1)
    {
        int len=end-start+1;    //截取的长度
        while(len--)
        {
            *(p++)=*(q_src++);
        }
        *(p++)='\0';
        return dst;
    }
    return NULL;

}

/* 函数名: substringbByString
 * 功  能: 字符串任意截取,通过字符串标明起始和结束位置
 * 用  法: char *substringbByString(char *dst,char *src,char *start,char *end)
 * 返回值: 如果起始和结束有效,返回参数dest的字符串起始地址,否则返回NULL
 * 说  明: 截取start到end指明字符串中间的字符串,不包括两端。start字符在src中只能有一个,end字符可以有多个,但以start后面那个为准
 * 安全性:目标地址dest一定要足够大,不然可能会溢出,后果不堪设想。
 */
char *substringByString(char *dst,char *src,char *start,char *end)
{
	char *p=dst; //等下要返回目标位置的首地址,所以不能直接用,地址会改变
	char *q_src=src;
	char* start_idx=strstr(q_src,start);
	//char* end_idx=strstr(q_src,end);
	char* end_idx=strstr(start_idx,end);	//从开始字符那里可以往后找
	if(start_idx==NULL||end_idx==NULL) //如果src中不存在start和end所指的字符串
		return NULL;
	int length=strlen(src);
	q_src=start_idx+strlen(start)*sizeof(char); //求起始位置地址
	if(q_src<end_idx)
	{
		 while(q_src<end_idx)
		 {
			 *(p++)=*(q_src++);
		 }
		 *(p++)='\0';
		 return dst;
	}
	return NULL;
}


int main(void)
 {
     //字符串拷贝
    char strcpy_destination[50];
    char *strcpy_source = "strcpy test";
    strcpy(strcpy_destination, strcpy_source);
    printf("用strcpy拷贝\"strcpy test\",结果:%s\n", strcpy_destination);  // 打印

    //字符串拷贝
    char strncpy_destination[50];
    char *strncpy_source = "strncpy test";
    strncpy(strncpy_destination, strncpy_source,3);
    printf("用strncpy拷贝\"strncpy test\"前3个字节,结果:%s\n",strncpy_destination);  // 打印

    //字符串拼接
    char strcat_destination[50];
    char *strcat_source_1="wu ";
    char *strcat_source_2="zu ";
    char *strcat_source_3="lie !";
    strcpy(strcat_destination,strcat_source_1);
    strcat(strcat_destination,strcat_source_2);
    strcat(strcat_destination,strcat_source_3);
    printf("\n用strcat拼接\"wu \" \"zu \" \"lie\",结果:\t%s\n",strcat_destination);  // 打印

    //将n个字符追加到字符串的结尾
    char strncat_destination[50];
    char *strncat_source_1="wu zu ";
    char *strncat_source_2="lie !";
    strcpy(strncat_destination,strncat_source_1);
    strncat(strncat_destination,strncat_source_2,5);
    printf("\n用strncat将\"lie !\" \"wu zu \"的后面,结果:\t%s\n",strncat_destination);  // 打印

    //字符串比较
    char *strcmp_source_1="wu zu lie";
    char *strcmp_source_2="wu zu lie";
    char *strcmp_source_3="wu";
    char *strcmp_source_4="wu zu lie !";
    char *strcmp_source_5="wu zu lie !";
    char *strcmp_source_6="abcdfghijklmnopq";
    printf("\n\"wu zu lie\"与\"wu zu lie\"比较,结果:\t%d\n",strcmp(strcmp_source_1,strcmp_source_2));
    printf("\"wu zu lie\"与\"wu\"比较,结果:\t\t%d\n",strcmp(strcmp_source_1,strcmp_source_3));
    printf("\"wu zu lie\"与\"wu zu lie !\"比较,结果:\t%d\n",strcmp(strcmp_source_1,strcmp_source_4));
    printf("\"wu zu lie !\"与\"wu zu lie\"比较,结果:\t%d\n",strcmp(strcmp_source_4,strcmp_source_1));
    printf("\"I am wu zu lie !\"与\"wu zu lie\"比较,结果:\t%d\n",strcmp(strcmp_source_5,strcmp_source_1));
    printf("\"wu zu lie\"与\"abc dfgh ijklmn opq\"比较,结果:\t%d\n",strcmp(strcmp_source_1,strcmp_source_6));

    //计算字符串的长度
    char *strlen_source_1="wu zu lie";
    printf("\n用strlen计算\"wu zu lie\"的长度,结果:\t%d\n",strlen(strlen_source_1));  // 打印

    //根据分界符将字符串分割成一个个片段
    char strtok_source_1[]="ab&cd&ef|gh:ij";
    char *p;
    printf("%s,\n", strtok(strtok_source_1, "&|:"));    //可以用多个字符,满足任何一个都会分割
    printf("%s,\n", strtok_source_1);   //分割出来的字符串放在原位置
    while((p = strtok(NULL, "&|:")))    //在第一次调用时,strtok()必须赋予参数s字符串,往后的调用则将参数s设置成NULL
        printf("%s,\n", p);
    printf("\n");

    //检索子串在字符串中首次出现的位置
    char strstr_source_1[]="wu zu lie!";
    char strstr_source_2[]="zu";
    char strstr_source_3[]="abc";
    printf("\n用strstr检索\"zu\"在\"wu zu lie\"中第一次出现的位置对应的地址,打印后面的字符,结果:\t%s\n",strstr(strstr_source_1,strstr_source_2));  // 打印
    printf("\n用strstr检索\"abc\"在\"wu zu lie\"中第一次出现的位置对应的地址,打印后面的字符,结果:\t%s\n",strstr(strstr_source_1,strstr_source_3));  // 打印

    //将字符串转换成整数(int)
    char *atoi_source_1="12345";
    int atoi_destination=0;
    atoi_destination=atoi(atoi_source_1);
    printf("\n用atoi将字符串\"12345\"转换成整数(int)12345,结果:\t%d\n",atoi_destination);  // 打印

    //将整数(int)转换成字符串
    int itoa_source_1 = 12345;
    char itoa_destination[25];
    itoa(itoa_source_1, itoa_destination, 10);  //10表示基数,也就是进制
    printf("\n用itoa将整数(int)12345转换成字符串\"12345\",结果:\t%s\n",itoa_destination);  // 打印


    //字符串任意截取
    char *substring_source_1="0123456789";
    char substring_destination[10];
    printf("\n用substring将字符串\"0123456789\"的第5到第8位截取出来,结果:\t%s\n",substring(substring_destination,substring_source_1,5,8));  // 打印

    //字符串任意截取,通过字符串标明起始和结束位置
    char *substringByString_source_1="0123456789";
    char substringByString_destination[10];
    printf("\n用substringByString将字符串\"0123456789\"中\"12\"和\"78\"之间的字符串截取出来,结果:\t%s\n",
           substringByString(substringByString_destination,substringByString_source_1,"234","9"));  // 打印


    //sprintf格式化输出函数
    int sprintf_source_1=12345;
    char sprintf_destination[10];
    sprintf(sprintf_destination,"%d",sprintf_source_1); //%8d:保留8位宽度(不够默认右对齐) %-8d:保留8位宽度且左对齐 %08d:保留8位宽度且前面不够补0 %4X:16进制转字节串,保留4位宽度(默认右对齐)
    printf("\n用sprintf将整数(int)12345转成字符串\"12345\"打印到sprintf_destination中,结果:%s|结束符|\n",sprintf_destination);  // 打印

    char *sprintf_source_2="12345";
    sprintf(sprintf_destination,"%-8.3s",sprintf_source_2); //%m.n在字符串的输出中,m表示宽度,字符串共占的列数;n表示实际的字符数。
    printf("\n用sprintf将字符串\"12345\"转成占位8实际字符数3的字符串\"     123\"打印到sprintf_destination中,结果:%s|结束符|\n",sprintf_destination);  // 打印

    float sprintf_source_3=3.1415926;
    sprintf(sprintf_destination,"%-5.2f",sprintf_source_3); //%m.n在浮点数中,m也表示宽度;n表示小数的位数。
    printf("\n用sprintf将浮点数\"3.1415926\"转成实际宽度5小数位2的字符串\" 3.14\"打印到sprintf_destination中,结果:%s|结束符|\n",sprintf_destination);  // 打印


    //snprintf格式化输出函数,和sprintf一样,只是加了大小限制
    int snprintf_source_1=123456;
    int snprintf_source_2=123;
    char snprintf_destination[5];
    snprintf(snprintf_destination,sizeof(snprintf_destination),"%d",snprintf_source_1);
    printf("\n用snprintf将整数(int)12345限定长度sizeof(snprintf_destination)转成字符串\"12\"打印到snprintf_destination中,(限定长度小于输入长度)结果:%s|结束符|\n",snprintf_destination);  // 打印
    snprintf(snprintf_destination,sizeof(snprintf_destination),"%d",snprintf_source_2);
    printf("\n用snprintf将整数(int)12345限定长度sizeof(snprintf_destination)转成字符串\"12\"打印到snprintf_destination中,(限定长度大于输入长度)结果:%s|结束符|\n",snprintf_destination);  // 打印
    snprintf(snprintf_destination,sizeof(snprintf_destination),"%8d",snprintf_source_1);    //(不同于sprintf!!!),%8d中不是控制最终的字节串长度,而是复制之前的长度,完成这个转换后,再进制前面sizeof(snprintf_destination)-1位的复制
    printf("\n用snprintf将整数(int)12345长度转成8位后再限定长度sizeof(snprintf_destination)复制打印到snprintf_destination中,结果:%s|结束符|\n",snprintf_destination);  // 打印
   /* int si=65535;
    sprintf(str, "%4X", si); //产生"123"
    puts(str);
    */
  /*  char str[10];
    snprintf(str, 9,"%d", 123456789); //产生"123"
    puts(str);
*/
    return 0;
 }



/* 函数名: strcpy
 * 功  能: 将参数src字符串拷贝至参数dest所指的地址
 * 用  法: char *strcpy(char *dest, const char *src);
 * 返回值: 返回参数dest的字符串起始地址
 * 说  明: 如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况,在编写程序时需特别留意,或者用strncpy()来取代;
 * 安全性:极度危险的函数,一不小心就会中招,危险指数:四星
 */

/* 函数名: strncpy
 * 功  能: 将字符串src前n个字符拷贝到字符串dest
 * 用  法: char *strncpy(char *dest, const char *src, size_t n);
 * 返回值: 返回参数dest的字符串起始地址
 * 说  明: 不像strcpy(),strncpy()不会向dest追加结束标记'\0';
 *         src和dest所指的内存区域不能重叠,且dest必须有足够的空间放置n个字符;
 */

/* 函数名: strcat
 * 功  能: 字符串拼接函数
 * 用  法: char *strcat(char *dest, const char *src);
 * 返回值: 返回dest字符串起始地址
 * 说  明: strcat() 会将参数src字符串复制到参数dest所指的字符串尾部;
 *         dest最后的结束字符'\0'会被覆盖掉,并在连接后的字符串的尾部再增加一个'\0';
 *         dest与src所指的内存空间不能重叠,且dest要有足够的空间来容纳要复制的字符串;
 * 安全性:造成缓冲区溢出的隐形杀手,危险指数 三星
 */

/* 函数名: strncat
 * 功  能: 将n个字符追加到字符串的结尾
 * 用  法: char *strncat(char *dest, const char *src, size_t n);
 * 返回值: 返回dest字符串起始地址
 * 说  明: strncat()将会从字符串src的开头拷贝n个字符到dest字符串尾部,dest要有足够的空间来容纳要拷贝的字符串;
 *         如果n大于字符串src的长度,那么仅将src全部追加到dest的尾部;
 *         strncat()会将dest字符串最后的'\0'覆盖掉,字符追加完成后,再追加'\0';
 */

/* 函数名: strcmp
 * 功  能: 字符串比较
 * 用  法: int strcmp(const char *s1, const char *s2);
 * 返回值: 根据ASCII码比较,若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值
 * 说  明: 它是区分大小写比较的,如果希望不区分大小写进行字符串比较,可以使用stricmp函数
 */

/* 函数名: strlen
 * 功  能: 计算指定的字符串s的长度,不包括结束字符'\0'
 * 用  法: size_t strlen(const char *s);
 * 返回值: 返回字符串s的字符数
 * 说  明: strlen() 函数计算的是字符串的实际长度,遇到第一个'\0'结束;
 *         如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到'\0'停止;
 *         sizeof返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen()是函数;
 */

/* 函数名: strtok
 * 功  能: 根据分界符将字符串分割成一个个片段
 * 用  法: char *strtok(char *s, const char *delim);
 * 返回值: 返回下一个分割后的字符串指针,如果已无从分割则返回NULL
 * 说  明: 当strtok()在参数s的字符串中发现到参数delim的分割字符时则会将该字符改为'\0'字符;
 *         在第一次调用时,strtok()必须赋予参数s字符串,往后的调用则将参数s设置成NULL;
 */

/* 函数名: strstr
 * 功  能: 检索子串在字符串中首次出现的位置
 * 用  法: char *strstr( char *str, char * substr );
 * 返回值: 返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL
 */

/* 函数名: atoi
 * 功  能: 将字符串转换成整数(int)
 * 用  法: int atoi (const char * str);
 * 返回值: 返回转换后的整型数;如果str不能转换成int或者str为空字符串,那么将返回0
 * 说  明: ANSI C规范定义了 stof()、atoi()、atol()、strtod()、strtol()、strtoul() 共6个可以将字符串转换为数字的函数,可以对比学习;
 *         另外在C99/C++11规范中又新增了5个函数,分别是 atoll()、strtof()、strtold()、strtoll()、strtoull();
 */

/* 函数名: sprintf() 格式化输出函数(图形)
 * 功能: 函数sprintf()用来作格式化的输出。
 * 用法: 此函数调用方式为int sprintf(char *string,char *format,arg_list);
 * 返回值: 如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。
 * 说 明: sprintf的作用是将一个格式化的字符串输出到一个目的字符串中,而printf是将一个格式化的字符串输出到屏幕。
 * 安全性:使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。解决这个问题,可以考虑使用 snprintf函数,该函数可对写入字符数做出限制。
 */

/* 函数名: snprintf() 格式化输出函数(图形)
 * 功能: 将可变参数 “…” 按照format的格式格式化为字符串,然后再将其拷贝至str中。
 * 用法: 此函数调用方式为int snprintf(char* dest_str,size_t size,const char* format,...);
 * 返回值: 如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。
 * 说 明: (1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
 *         (2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度。
 */

猜你喜欢

转载自blog.csdn.net/qq_18677445/article/details/103862497