linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux基础建设 >

C语言字符串基本操作

时间:2019-05-14  来源:未知  作者:admin666

在 C 语言中,字符串是由数字、字母、下划线组成的一维字符数组,并且使用 null 字符 '\0' 作为终止符号。字符串在存储上类似字符数组,所以它每一位的单个元素都是可以提取的,如s=“abcdefg”,则s[0]=“a”,s[1]="b"。

字符实际上是以对应的ASCII数值的形式在内存中存储的。 对一个字符强制转换成int类型,得到的就是该字符的ASCII码。

字符与字符相减,其实就是它们对应的ASCII码相减,得到的是它们的ASCII码之间相差的距离。

C中函数返回字符串的4种方法

函数返回字符串的两个条件 1. 返回一个字符串地址(首地址), 2. 保证这块地址的内存空间不会随着函数退出而销毁
1.将字符串指针作为函数参数传入,并返回该指针
2.使用malloc申请的堆空间,返回申请的堆地址,注意释放
3.返回一个static定义的静态局部变量
4.使用全局变量


1.  将字符串指针作为函数参数传入,并返回该指针

这种方法一般在函数内复制一份该字符串指针的首地址,通过它操作首地址指向的元素,及其后边的元素,这样操作 就相当于直接操作原始字符串内容。例如strcpy函数:


char* strcpy(char* des,const char* source)
  {
      char* r=des;
      assert((des != NULL) && (source != NULL));
      while((*r++ = *source++)!='\0');
      return des;
  }

 

2. 使用malloc函数动态分配内存,函数可以返回该内存地址

malloc申请的内存位于堆上,不会被系统自动释放掉,可以从函数中返回,但是切记要在主调函数中使用free主动释放该空间。


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

  char * return_Pchar_malloc()
  {
      char * str2;
      str2 = (char *)malloc(10);
      strcpy(str2,"Hello!");
      return str2;
  }

  int main()
  {
      char * str1;
      str1 = return_Pchar_malloc();
      printf("%s\n",str1);
      //记住一定要用free释放,否则会造成内存泄露
      free(str1);
      return 0;
  }


3. 返回一个静态局部变量

使用static修饰的静态变量存放位置是在全局数据区,在主程序运行的整个生命周期中都存在,不会随着函数的退出而销毁。


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

  char * return_Pchar_static()
  {
      static char str2[10];
      strcpy(str2,"Hello!");
      return str2;
  }

  int main()
  {
      char * str1;
      str1 = return_Pchar_static();
      printf("%s\n",str1);   
      return 0;
  }

 


4. 使用全局变量

全局变量是老大,没啥说的。

 

那么可否在函数中返回一个常量字符串指针?如下:


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

char* return_pstr(){
    char* str = "HELLO";
    return str;
 }

int main(){
    char * str = return_pstr();
    printf("%s\n",str);
 }

 

答案是可以的,但也是危险的!

字符常量位于静态数据区里的文字常量区,生命周期是整个函数,但是字符常量是只读的,任何尝试修改字符常量的操作都会导致运行错误。

 


1. 数字转换成字符串、 字符串转换成数字

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

//数字转换成字符串
void itoa(int num,char* str){
    int i=0,length=0,temp=0;
   
    while(num>0){
        str[i]=num%10+'0'; //数字+'0'转换成字符
        i++;
        num=num/10;
    }
    str[i]='\0';
   
    length = strlen(str);
    //字符逆序,注意终止条件是长度的一半
    for(int j=0;j<length/2;j++){
        temp = str[j];
        str[j] = str[length-j-1];       
        str[length-j-1] = temp;
    }
}

//字符串转换成数字
int char_to_num(char* str){
    int i=0, temp = 0;
    while(str[i]){
      temp = temp*10+(str[i]-'0');
      i++;
    }
    return temp;
}
 
int main(){ 
    int num = 12343245;
    int c_n;
    char str[10];
    itoa(num,str);
    c_n = char_to_num(str);
    printf("%s\n",str);
    printf("%d\n",c_n); 
    return 0;
}

 


 2. 实现 strcpy 字符串复制

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

//实现两个字符串复制
char* strcpy_(char* strS, char* strT){
    char* temp = strT;
    if(strS==NULL||strT==NULL){return NULL;}
    while((*temp++=*strS++)!='\0');
    return strT;  //返回的是字符串首地址
}


int main(){
    char strS[6]="12345";
    char strT[6];
    char* ss;
    ss = strcpy_(strS,strT);
    printf("%s\n\n",ss); 
    printf("%s\n",strT);
    return 0;
}

 


 3. 字符串循环右移n位

 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
//字符串循环移动n位
char* strCir(char* str, int n){
    int length = strlen(str);
    char* temp=(char*)malloc(length+1);   
    n =n%length;
    for(int i=0;i<length;i++){     
        int move = i+n;
        if(move>=length){
            move=move%length;
        }     
        temp[move]=str[i];       
    }
    temp[length]='\0';   
    return temp; //返回的是字符串首地址
}
 
 
int main(){   
    char str[]="ABCDEFG12345";   
    char* str_right = strCir(str,8);
    printf("%s\n\n",str); 
    printf("%s\n",str_right);
    free(str_right); //记得释放malloc内存
    return 0;
}

 


 4. 字符串逆序,以单词为单位逆序


 如给定字符串“This is a sentence”,转换成"sentence a is This"。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//反转区间字符串
void reverse_Str(char* left, char* right){
    while(left<right){
        char temp = *left;
        *left = *right;
        *right = temp;       
        left++;
        right--;
    }
}

//字符串以单词为单位逆序
char * str_reverst(char * str, char key){
    if(str==NULL){return str;}
    char* start=str, *end=str, *kstr=str;
    while((*++end)!='\0');   
    end--; 
    reverse_Str(start,end);  //整个字符串逆序
   
    while(*start!='\0'){
        if(*start==key){
            reverse_Str(kstr,start-1);  //对中间单词逆序
            kstr=start+1;
        }       
        start++;
    }
    reverse_Str(kstr,start-1); //对最后一个单词逆序
    return str;
}


int main(){   
    char str[45]="ABC DE FG B HIGK";   
    char* str_reverse = str_reverst(str,' ');
    printf("%s\n",str_reverse);     
    return 0;
}

 

 

5. 求母串中子串出现的次数

 

如"abcrtabc"中字串"abc"出现的次数是2。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//子串出现次数
int count(char* str, char *str_son){
    if(*str=='\0'||*str_son=='\0'){return 0;}
    char* s0, *s1;
    int amount = 0;
    while(*str!='\0'){
        s0 = str; s1 = str_son;
        while((*s0==*s1)&&(*s0!='\0')&&(*s1!='\0')){
            s0++; s1++;           
        }       
        if(*s1=='\0'){
            amount+=1;           
        }
        str++;
    }
    return amount;
}


int main(){   
    char str[]="abcrtabc";
    printf("%d\n",count(str,"abc"));     
    return 0;
}

 

 

6. 查找第一个匹配字串的起始位置

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

//首个匹配字串的起始位置
int position(char* str,int n, char *str_son,int n_son){
    if(*str=='\0'||*str_son=='\0'){return -1;}
    if(n<=0||n_son<=0||n_son>n){return -1;}
    int i=0;
    for(;i<n-n_son;i++){
        if(*str!=(*str_son)){
            str++;         
        }
        else{
            for(int j=0;j<n_son;j++){
                if(str[j]!=str_son[j]){
                    break;
                }             
            }
            return i;
        }
    }
    return -1;
}
 

int main(){   
    char str[]="abcdefghigklmn";
    printf("%d\n",position(str,strlen(str),"klm",strlen("klm")));     
    return 0;
}

 

7. 求两个字符串的最大公共子串


 给定字符串A和B,输出A和B中的最大公共子串。比如A="aocdfe" B="pmcdfa" 则输出"cdf"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//两个字符串的最大公共字串(重要)
char* max_sub_str(char* str1,int str1_l, char* str2, int str2_l){
    char* max_sub = (char*)malloc(100*sizeof(char));
    char* max_sub_help = (char*)malloc(100*sizeof(char));
    int p_str1,p_str2,p_str_help;
    for(int i=0;i<str1_l;i++){    //最好先判断哪个str长
        for(int j=0;j<str2_l;j++){
            p_str1 = i;
            p_str2 = j;
            while(str1[p_str1]==str2[p_str2]){
                max_sub_help[p_str_help]=str2[p_str2];
                p_str1++;
                p_str2++;
                p_str_help++;
            }
            if(strlen(max_sub_help)>strlen(max_sub)){
                strcpy(max_sub,max_sub_help);
            }
            p_str_help=0;
        } 
    }
    free(max_sub_help);
    return max_sub; 
}
 

int main(){   
    char str[]="abcdefg";
    char* sub_str = max_sub_str(str,7,"efghi",5);
    printf("%s\n",sub_str);
    free(sub_str);     
    return 0;
}

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

上一篇:没有了
友情链接
  • Mozilla发布Firefox 67.0.4,修复沙箱逃逸漏洞
  • 蚂蚁金服正式成为CNCF云原生计算基金会黄金会员
  • Firefox 68将采用Microsoft BITS安装更新
  • OpenSSH增加对存储在RAM中的私钥的保护
  • 谷歌想实现自己的curl,为什么?
  • Raspberry Pi 4发布:更快的CPU、更大的内存
  • Firefox的UA将移除CPU架构信息
  • Ubuntu放弃支持32位应用程序实属乌龙,Steam会否重回Ubuntu怀抱
  • Qt 5.13稳定版发布:引入glTF 2.0、改进Wayland以及支持Lottie动
  • 红帽企业Linux 7现已内置Redis 5最新版
  • Slack进入微软内部禁用服务清单,GitHub也在其列?
  • 安全的全新编程语言V发布首个可用版本
  • Windows Terminal已上架,快尝鲜
  • 阿里巴巴微服务开源生态报告No.1
  • 面世两年,Google地球将支持所有基于Chromium的浏览器
  • 推进企业容器化持续创新,Rancher ECIC千人盛典完美收官
  • CentOS 8.0最新构建状态公布,或于数周后发布
  • Debian移植RISC
  • 微软拆分操作系统的计划初现雏形
  • Oracle发布基于VS Code的开发者工具,轻松使用Oracle数据库
  • Ubuntu 19.10停止支持32位的x86架构
  • 微软为Windows Terminal推出全新logo
  • 联想ThinkPad P系列笔记本预装Ubuntu系统
  • 微软发布适用于Win7/8的Microsoft Edge预览版
  • 启智平台发布联邦学习开源数据协作项目OpenI纵横
  • 经过六个多月的延迟,微软终于推出Hyper
  • ZFS On Linux 0.8.1 发布,Python可移植性工作
  • DragonFly BSD 5.6.0 发布,HAMMER2状态良好
  • Linux Kernel 5.2
  • CentOS 8.0 看起来还需要几周的时间
  • 百度网盘Linux版正式发布
  • PCIe 6.0宣布:带宽翻倍 狂飙至256GB/s
  • PHP 7.4 Alpha 发布,FFI扩展,预加载Opcache以获得更好的性能
  • Canonical将在未来的Ubuntu版本中放弃对32位架构的支持
  • Scala 2.13 发布,改进的编译器性能
  • 微软的GitHub收购了Pull Panda,并且使所有订阅完全免费
  • Windows Subsystem for Linux 2 (WSL 2)现在适用于Windows 10用
  • Debian 10 “Buster”的RISC
  • MariaDB宣布发布MariaDB Enterprise Server 10.4
  • DXVK 1.2.2 发布,带来微小的CPU开销优化
  • DragonFlyBSD 5.6 RC1 发布,VM优化,默认为HAMMER2
  • PrimeNG 8.0.0 发布,支持Angular 8,FocusTrap等
  • GIMP 2.10.12 发布,一些有用的改进
  • 清华大学Anaconda 镜像服务即将恢复
  • Debian GNU/Linux 10 “Buster” 操作系统将于2019年7月6日发布
  • 时时彩论坛
  • 五星体育斯诺克
  • 北单比分直播
  • 河北11选5走势图
  • 福建体彩36选7开奖结果
  • 九龙图库下载