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

上一篇:没有了
友情链接
  • WSL Arch Linux已正式登陆Microsoft Store应用商店
  • GNU调试器 GDB 8.3 发布及安装更新,支持RISC
  • OpenMandriva Lx 4.0将Python 2排除在其基本操作系统之外
  • Linux 5.1.1 发布,几个修复
  • Wine
  • Android Studio 3.5 Beta 发布,性能优化改进
  • Firefox和GNOME最终可以在Linux 5.2的AFS文件系统上运行
  • DifferentialEquations.jl v6.4.0 发布,用于微分方程高性能求解
  • RHEL 8发布后,用户等待CentOS 8的推出
  • Libinput 1.13.2 发布,为苹果TouchPad提供更好的手指检测功能
  • GTK 3.96 发布,作为向GTK 4.0迈进的又一步
  • Phoronix Test Suite v8.8.0m3 发布,开源基准测试
  • CentOS 8.0作为Red Hat Enterprise Linux 8.0社区版重新构建的进
  • GNOME 3.32.2桌面环境发布,最新的bug和安全修复
  • LWJGL 3.2.2 发布,针对Vulkan 1.1和其他新包的更新
  • Mesa 19.0.4 发布,许多RADV, RadeonSI和Intel修复
  • Krita 4.2 Alpha带来性能改进,其他数字绘画增强功能
  • 英特尔为BFloat16添加GCC 10和LLVM Clang 9编译器支持
  • ZFS On Linux 0.8
  • 适用于Ubuntu手机的Ubuntu Touch OTA
  • Kaidan作为Jabber/XMPP聊天客户端加入KDE
  • Google在Chrome中发布新的Cookie控件,改善用户隐私
  • 微软开源PowerToys,计划推出Windows 10版本
  • Linux内核将很快默认情况启用“
  • 由于证书问题,Mozilla延迟Firefox 67推出
  • Radeon ROCm 2.4 发布,兼容TensorFlow 2.0
  • Wine 4.8采用Unicode 12.0更新,更好地支持操纵杆
  • Google宣布Kotlin为Android应用程序开发的首选语言
  • 面向Windows 10的Chromium Microsoft Edge Beta泄露
  • KDE Plasma 5.16推出重写的通知系统
  • 币安交易所被黑客入侵,超过7000比特币被盗
  • Vivaldi 2.5 发布,世界上第一个与Razer Chroma集成的Web浏览器
  • Debian 10 “Buster” 目前在GNOME默认使用Wayland,但仍有可能
  • Linux 5.2中的XFS获得“大量新东西”
  • Firefox 66.0.5发布,包含针对扩展Bug的更多修复
  • Unity 2019.2 Beta 发布,带来许多Linux和Vulkan补丁
  • qBittorrent 4.1.6发布! 如何在Ubuntu 18.04中安装它
  • Linux新闻 第971页
  • MongoDB 日志切割三种方式
  • MongoDB Oplog深入理解
  • MongoDB 副本集搭建与管理详解
  • MongoDB 备份与还原 mongodump、mongorestore
  • MongoDB 常用的几大GUI工具
  • 微软开源Xamarin API Docs
  • Chrome浏览器将不再允许网站劫持后退按钮
  • 福彩3d试机号查询
  • 彩票平台
  • 福彩3d开奖直播
  • 凤凰时时彩平台网址
  • 温岭六家统记牌器