C语言回顾--常见的字符串操作

本文总结了C语言中常见的字符串处理技巧,包括整数与字符数字互换、字符串复制、strstr()函数实现、strcat()函数、快慢指针对字符串的操作、字符串逆序以及字符串循环移位判断等。通过实例解析了各种操作的实现方法和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 


前言:

笔试题基本上必考题之一:字符串的处理,涉及到指针、数组、以及字符串数组;近几日的笔试字符串处理让我无从下手,因此根据近几日的笔试题,总结了一波常见的操作;


1.整数与字符数字互换类型:

void char_to_int( char *buf, int *num,int size)    //字符串换成数字
{
    int         i = 0;
    int         temp = *num;

    if( buf == NULL || num == NULL || size <=0)
    {
        printf("Error:error arg\n");
        return ;
    }

    while( buf[i] != 0 )                                            //遍历跳出条件:当碰到0退出循环就是'\0'=0

    {
        temp = temp*10 + (buf[i] - '0');                  //利用字符减字符的ASCII值获得int类型值后,通过累乘10来表示十进制当中的个、十、百位;
        i++;
    }
    *num = temp;
}

void int_to_char( int num,char *buf,int size)    //数字换成字符串
{
    int         i = 0,j = 0;
    char        temp[size];

    while(num)                                            //遍历跳出条件:判断数字是否为0

    {

        temp[i] = num%10 +'0';                    //对各个位进行取余,从而取得各个位上0~9的数值,在通过加上字符'0'的ASCII值进行相加,化成对应'0'~'9'的ASCII值
        i++;
        num = num/10;                                 //获取个、十、百位                      
    }

    temp[i] = 0;                                            //当跳出循环时,字符串必须以\0结尾,而0 = '\0',并且到这里时这个字符串是逆序的,需要调整为正序;
    while(i >= 0)                                            //调为正序

    {
        buf[j] = temp[i-1];
        j++;
        i--;
    }
    buf[j] = 0;                                            //同样给字符串进行结尾
}

注:需要强调的是,函数传参是按值传递,所以你想保存则需要指针的协助,让其按地址传递;或者,可以通过函数的返回值来存储到相应的函数区;

注:这个例题可以辅助剑指offer里面的面试案例(关于字符串转换)一起食用,效果更佳;

2.字符串复制函数问题:

功能:将src所指向的字符串覆盖到dest所指向的字符串:比如,src:123 dest:12 返回12

char *strcopy(char *dest, const char *src)
{
    if( dest == NULL || src == NULL )
    {
        printf("Error:error arg\n");
        return NULL;
    }

    while( *dest != 0 || *src != 0 )    //
    {
        *(dest++) = *(src++);    //变量之间赋值,并且表示字符串个个字符;
    }
    *dest = 0;
    return dest;

}

3.strstr()函数的实现:

功能介绍:strstr()函数是把主串中的字串及以后的字符全部返回:比如,主串:1234,字串是23,则返回234;

char *strstr1(char *string,const char *strCharSet)    //在主串中寻找字串
{
    int             i;
    int             j;
    int             temp;

    if( string == NULL || strCharSet == NULL )
    {
        printf("Error:error arg\n");
        return NULL;
    }

    for( i = 0 ; string[i] != '\0'; i++)    //在主串中进行遍历,遇到'\0'退出循环
    {
        j = 0;
        temp = i;        //用于保存i的位置

        if(string[i] == strCharSet[j])    //主串的第一个字符和子串的第一个字符进行匹配
        {
            while(string[i++] == strCharSet[j++])    //第一个字符匹配成功后,继续匹配下去
            {
                if((strCharSet[j] == '\0'))        //直到字串遇到结束符
                    return &string[i-j];            //要求返回的是与子字串相同的第一个字符起的主串地址;
            }
            i = temp;    //下一个字符不匹配则返回,并且回到刚刚的位置;
        }

    }
        return NULL;

}

4.实现strcat()函数

功能介绍:连接两个字符串并连接好后的字符串保存在第一个字符串当中;

char *strcat1(char *dest,char *src)
{
    char *p = dest;            //利用指针的作用
    
    if( dest == NULL || src == NULL )
    {
        printf("Error:error arg\n");
        return NULL;
    }

    while( *p != 0 )    //不对原来的字符串进行操作,但需要知道末尾位置;
    {
        p++;
    }

    while((*p++ = *src++)!= 0 );    与strcpy核心语句操作相同;
    
    return dest;

}

注:如果char arr[8]; 则 *arr++可以用来遍历字符串,而(*arr)++则表示第一个字符串的字符+1 'h' -> 'i';arr[1~7]代表变量,如果要取地址,则&arr[1~7]; 

 

5.字符串操作之快慢指针:

功能介绍:

使用快慢指针好处在于:函数体不要额外分配数组空间

快慢指针用法很多,快指针用于查找特定的字符,然后用来覆盖慢指针指向的地址上的值;

例1:在字符串str1中删除str2字符串中出现的字符,如:str1:abcaaa str2: ac 输出结果为:str1:b

快指针:pfast指向str1,用来查找不需要删除的字符;

慢指针:pslow指向str1,用于存放快指针找到的字符;

 

找到不需要的删除的字符,进行如下操作:

*pslow++=*pfast++;

找到需要删除的字符,进行如下操作:

pfast++;

void Delete_str(char *str1,char *str2)
{
    char *pfast=str1;
    char *pslow=str1;
    char *p2=str2;

    if(str1 == NULL || str2 == NULL)
    {
        printf("Error:arg error!\n");
        return;
    }

    while(*p2 != 0)            //指针p2从str2的第一个字符开始在字符串str1进行匹配,如果使用哈希表则时间复杂度要低也快,想实现自行百度;
    {
        while(*pfast != 0)    //用快指针进行遍历,本层循环结束条件为:快指针在遍历完一次字符串str1
        {
            if(*pfast != *p2)    //不匹配的字符操作
            {
                *pslow = *pfast;
                pslow++;
            }
            pfast++;                //剩下的都是匹配字符的操作
        }

        *pslow = *pfast;    //遍历完一次后,重新指向

        pslow = str1;    //遍历完一次后,重新指向
        pfast = str1;    //遍历完一次后,重新指向
        p2++;    //遍历完一次后,p2向下一个地址移动;

    }
    *pslow = *pfast;    //此时*pfast为'\0'赋值给*pslow进行结尾;
}

例2:合并字符串间连续多个空格如输入:___a___b__c___(其中"_"表示空格)输出结果为:a_b_c

同样使用快慢指针来操作:

快指针:用于查找小写字母的字符;

慢指针:用于覆盖当前地址上的字符;

 

找到非空格字符的操作:

*pslow++=*pfast++;

找到空格字符的操作:

*pslow++=*pfast++;

for(;*pfast == ' '; pfast++);

 

int main()
{
    char        str[100];
    char        *pfast = str;
    char        *pslow = str;

    printf("pfastlease inpfastut strings:");
    gets(str);

    while(*pfast == ' ')            //忽略非空字符前面的空格字符;
    {
        pfast++;
    }

    while(*pfast != 0)            //遍历str1直到/0
    {
        if((*pfast >= 'a' && *pfast <= 'z'))    //不是空格字符的操作;
        {
            *pslow++=*pfast++;
        }
        else                                                    //空格字符的操作;
        {
            *pslow++ = *pfast++;
            for(;*pfast == ' ' ;pfast++);
        }
    }

    if(*(pslow-1) == ' ')                    //快指针指向最后一个字符后面有空格
    {
        *(pslow-1) = 0;
    }
    else                                            //快指针指向最后一个字符后面没有空格
    {
        *pslow = 0;
    }

    printf("str =%s\n",str);

    return 0;
}

变式:

将字符串中,字符首和尾的空格去掉去掉:

int remove_blank(char *str)
{
    char   *s=str;
    char   *p=str;

    if( !str || strlen(str)<=0 )
        return -1; 
       
    /*  find the first character is not blank from head */
   
    while( *s!='\0' && isblank(*s) )
    {   
        s++;
    }   
                
           
    /*  copy the left characters to string head */
   
    while(*s!='\0') 
        *p++=*s++;
        
    /*  end of '\0'  */
    *p='\0';
    
    /*  find end character position */
   
    s = &str[strlen(str)-1];
   
    /*  find all the end blank character  */
   
    while( isblank(*s) )
    {   
    
        s--;
       
    }   
    *(s+1) = '\0';
                                  
    return 0;
}

 

6.字符串逆序操作:比如:abcd 输出为dcba

有两种方法实现字符串逆序:

  1. 使用首尾交换的方式进行逆序;

  2. 分配新空间操作;

 

笔试通常是第一种情况,甚至不让你使用字符串处理函数;

定义2个变量,分别为i和j,其中i用来从字符串头开始向尾部遍历,j从尾部开始向首部遍历,循环结束条件为i<=j (其中<的情况为字符串的字符为偶数个,=为奇数个)

void nixuString(char * str)
{
    int i = 0,j = 0;
    char temp;
    char *Sp = str;

    while(*Sp != '\0')    //计算字符串长度
    {
        j++;
        Sp++;
    }

    j=j-1;            //算上了\0需要-1

    while(i <= j)    //其中<的情况为字符串的字符为偶数个,=为奇数个
    {

        temp = str[i];        //交换
        str[i] = str[j];
        str[j] = temp;
      
        i++;
        j--;
    }

    printf("str:%s\n",str);
}

main函数实现体:

char_to_int()、int_to_char()函数在main函数的调用用例;

int main()
{
    int     num = 12345;
    int     temp_num = 0;
    char    temp_str[7];
    char    str[7] = {'1','2','3','4','5'}; 
   
#if 1 
    int_to_char(num,temp_str,7);
    printf("str:%s\n",temp_str);
#endif

#if 0 
    char_to_int(str,&temp_num,7);
    printf("str:%d\n",temp_num);
#endif

7.字符串循环移位包含操作:

给定两个字符串s1,s2,要求判断s2能否被s1循环移位得到的字符串包含。

例如给定s1="AABCD"和s2="CDAA“,返回true ;给定s1="ABCD"和s2="ACBD",返回false。

实现函数bool_cyc_shift(char *s1,char *s2)函数

/*********************************************************************************
 *      Copyright:  (C) 2018 Guo Zhihao
 *                  All rights reserved.
 *
 *       Filename:  xunhuanweiyi.c
 *    Description:  字符串移位循环 返回值:符合条件:ture,不符合条件false
 *                 
 *        Version:  1.0.0(10/15/2018)
 *         Author:  Guo Zhihao <810170156@qq.com>
 *      ChangeLog:  1, Release initial version on "10/15/2018 06:40:09 PM"
 *                 
 ********************************************************************************/
#include<stdio.h>
#include<stdbool.h>
#include<string.h>

bool bool_cyc_shift(char *s1,char *s2,int len1,int len2) //字符串s1,s2,以及对应的长度len1,len2
{
    int i;
    if(s1 == NULL || s2 == NULL || len1 < len2)        //判断传参
            return false;

    for(i=0;i<len1;i++)                                
    {
        int j = 0;
        for(;j<len2;j++)
        {
            if(s2[j] != s1[(i+j)%len1])                //移位循环匹配字符
                break;
        }
        if( j == len2 )                                //符合条件为:遍历完s2,否则不符合条件则会先遍历完s1;
            return true;
    }

    return false;
}

int main() 
{
    char s1[] = "AABCD";
    char s2[] = "CDAA";

    bool   result;

    int len1 = strlen(s1);
    int len2 = strlen(s2);

    result = bool_cyc_shift(s1,s2,len1,len2); 

    printf("result = %d\n",result);
    
    return 0;
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值