当前位置:首页 > > 嵌入式微处理器
[导读]C语言字符串操作知识!

#字符串倒序输出

实现逻辑,通过strlen获取字符串长度,然后通过 len/2 进行交叉赋值,这里需要注意,不需要考虑len是奇数还是偶数的问题。

如果len是奇数,最后一个字符就不需要倒序,如果是偶数,最后两个字符就倒序。

#include "stdio.h"

void rechange_str(char *str)
{
 int i, len;
 char tmp;
 if (NULL == str) {
  return ;
 }
 len = strlen(str);
 for (i = 0; i < len/2; i ++) {
  tmp = str[i];
  str[i] = str[len-i-1];
  str[len-i-1] = tmp;
 }
}

int main(void)
{
 char str[20] = "hello,world";
 printf("%s\n",str);
 rechange_str(str);
 printf("%s\n",str);
 return (0);

程序输出

hello,world
dlrow,olleh

--------------------------------
Process exited after 0.02841 seconds with return value 0
请按任意键继续. . .

#整型转字符串

实现逻辑,每个整数看其转换进制,从个位到十位百位都可以通过%操作加上/操作获得,再用一个字符数组保存0-F。

用个位数对应值转为字符,注意转换出的字符串是反向的,还要考虑传入的若是负数如何处理,再用翻转字符串完成最后整个操作

下面这段代码需要好好研究一下,最好自己运行试试。

#include "stdio.h"

char *sky_itoa(int value, char *str, unsigned int radix)
{
 char list[] = "0123456789ABCDEF";
 unsigned int tmp_value;
 int i, j, k;
 if (NULL == str) {
  return NULL;
 }
 if (2 != radix && 8 != radix && 10 != radix && 16 != radix) {
  return NULL;
 }
 i = 0;
 k = 0;
 if (radix == 10 && value < 0) {
  tmp_value = (unsigned int)(0 - value);
  str[i++] = '-';
  k = 1;
 } else {
  tmp_value = (unsigned int)value;
 }
 do {
  str[i++] = list[tmp_value%radix];
  tmp_value /= radix;
 } while(tmp_value);
 str[i] = '\0';
 //翻转
 char tmp;
 for (j = k; j < (i+k)/2; j++) {
  tmp = str[j];
  str[j] = str[i+k-j-1];
  str[i+k-j-1] = tmp;
 }
 return str;
}

int main(void)
{
 int a = 1254545;
 char str[100] ={0};

 printf("%s\n",sky_itoa(a,str,2));
 printf("%s\n",sky_itoa(a,str,8));
 printf("%s\n",sky_itoa(a,str,10));
 printf("%s\n",sky_itoa(a,str,16));
 return (0);

程序输出

100110010010010010001
4622221
1254545
132491

--------------------------------
Process exited after 0.02963 seconds with return value 0
请按任意键继续. . .

#字符串复制

实现逻辑,逐个赋值直到遇到'\0'停止即可

#include "stdio.h"

char *sky_strcpy(char *dst, const char *str)
{
 if (NULL == dst ||  NULL == str) {
  return NULL;
 }
 char *ret = dst;
 while (*str != '\0') {
  *dst ++ = *str ++;
 }
 return ret; 


int main(void)
{
 char str_1[100] = "hello,world";
 char str[100] ={0};

 sky_strcpy(str,str_1);
 printf("str_1:%s\n",str_1);
 printf("str:%s\n",str);
 return (0);

程序输出

str_1:hello,world
str:hello,world

--------------------------------
Process exited after 0.03334 seconds with return value 0
请按任意键继续. . .

#字符串比较

1、正常比较是否相同 实现逻辑,判断字符串长度是否相同,若相同逐个比较字符是否相同

#include "stdio.h"

int sky_strcmp(char *dst, char *str)
{
 int i, len;
 if (NULL == dst || NULL == str) {
  return 0;
 }
 if (strlen(dst) != strlen(str)) {
  return 0;
 }
 len = strlen(dst);
 for (i = 0; i < len; i++) {
  if (*dst++ != *str++) {
   return 0;
  }
 }
 return 1;


int main(void)
{
 char str_1[100] = "hello,world";
 char str_2[100] = "hello,world";
 char str[100] = "adfs";
 
 printf("%d\n",sky_strcmp(str_1,str));
 printf("%d\n",sky_strcmp(str_1,str_2));
 return (0);

程序输出

0
1

--------------------------------
Process exited after 0.02802 seconds with return value 0
请按任意键继续. . .

2、忽略大小写字符串比较

实现逻辑,在比较字符时可以将其统一转换为大写或小写,然后再进行比对即可,和正常对比无其他不同

 #include "stdio.h"
 
 #define CONVERT(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) - 'A' + 'a') : (c))
 int sky_strcmp(char *dst, char *str)
 {
  int i, len;
  if (NULL == dst || NULL == str) {
   return 0;
  }
  if (strlen(dst) != strlen(str)) {
   return 0;
  }
  len = strlen(dst);
  for (i = 0; i < len; i++) {
   if (CONVERT(*dst) != CONVERT(*str)) {
    return 0;
   }
   dst ++;
   str ++;
  }
  return 1;
 } 
 
 int main(void)
 {
  char str_1[100] = "heLlo,world";
  char str_2[100] = "hello,world";
  char str[100] = "adfs";
  
  printf("%d\n",sky_strcmp(str_1,str));
  printf("%d\n",sky_strcmp(str_1,str_2));
  return (0);
 } 

程序输出

0
1

--------------------------------
Process exited after 0.04624 seconds with return value 0
请按任意键继续. . .

#memcpy函数实现

实现逻辑,主要就是逐个赋值即可完成 

1、不考虑拷贝覆盖问题

#include "stdio.h"
#include "string.h"

void *sky_memecpy(void *dst, const void *str, int n)
{
 if (NULL == dst || NULL == str || n <= 0) {
  return NULL;
 }
 char *pdst = (char *)dst;
 char *pstr = (char *)str;
 while (n --) {
  *pdst ++ = *pstr ++;
 }
 return dst;
}

int main(void)
{
 char str_1[100] = "heLlo,world";
 char str_2[100] = "sdfsdfs";
 sky_memecpy(str_2,str_1,strlen(str_1));
 printf("%s\n",str_2);
 return (0);

程序输出

heLlo,world

--------------------------------
Process exited after 0.02516 seconds with return value 0
请按任意键继续. . .

2、考虑拷贝覆盖问题

拷贝覆盖是我们在拷贝字符串的时候需要注意的一个问题,我下面的示例程序,使用第一个函数的时候,就出现了问题,使用第二个函数就没有出现问题。

原因是,我们源字符串和目的字符串的地址都是一样的,我们希望把字符串往后移动一个位置,但是实际上出现了问题。

 #include "stdio.h"
 #include "string.h"
 
 void *sky_memecpy_1(void *dst, const void *str, int n)
 {
  if (NULL == dst || NULL == str || n <= 0) {
   return NULL;
  }
  char *pdst = (char *)dst;
  char *pstr = (char *)str;
  while (n --) {
   *pdst ++ = *pstr ++;
  }
  return dst;
 }
 
 void *sky_memecpy(void *dst, const void *str, int n)
 {
  if (NULL == dst || NULL == str || n <= 0) {
   return NULL;
  }
  char *pdst = (char *)dst;
  char *pstr = (char *)str;
   
  if (pdst > pstr && pdst < pstr + n) {
   pdst = pdst + n - 1;
   pstr = pstr + n - 1;
   while (n --) {
    *pdst -- = *pstr --;
   }
  } else {
   while (n --) {
    *pdst ++ = *pstr ++;
   }
  }
  return dst;
 }
 
 int main(void)
 {
  char str_1[100] = "heLlo,world";
  char str_2[100] = "heLlo,world";
  sky_memecpy_1(str_1+1,str_1,strlen(str_1));
  printf("%s\n",str_1);
  
  sky_memecpy(str_2+1,str_2,strlen(str_2));
  printf("%s\n",str_2);
  return (0);
 } 

程序输出

hhhhhhhhhhhh
hheLlo,world

--------------------------------
Process exited after 0.02773 seconds with return value 0
请按任意键继续. . .

针对上面的拷贝覆盖问题,单独写了一个测试程序

#include "stdio.h"
#include "string.h"

void *sky_memecpy(void *dst, const void *str, int n)
{
 if (NULL == dst || NULL == str || n <= 0) {
  return NULL;
 }
 char *pdst = (char *)dst;
 char *pstr = (char *)str;
 while (n --) {
  printf("dst:%c--->str:%c\n",*pdst,*pstr);
  *pdst ++ = *pstr ++;
 }
 return dst;
}

int main(void)
{
 char str_1[100] = "heLlo,world";
 sky_memecpy(str_1+1,str_1,strlen(str_1));
 printf("%s\n",str_1);
 return (0);

程序输出

dst:e--->str:h
dst:L--->str:h
dst:l--->str:h
dst:o--->str:h
dst:,--->str:h
dst:w--->str:h
dst:o--->str:h
dst:r--->str:h
dst:l--->str:h
dst:d--->str:h
dst: --->str:h
hhhhhhhhhhhh

--------------------------------
Process exited after 0.02575 seconds with return value 0
请按任意键继续. . .

初始的时候,dst指向 e 字符,str 指向h 字符,然后每次都是dst先移动,str再移动,就出现了dst被h字符所覆盖。

好了,就这些内容,希望大家好好消化,这些代码对面试很有帮助。


END

来源:嵌入式Linux

版权归原作者所有,如有侵权,请联系删除。

推荐阅读

飞机上一般是什么操作系统?

高速CAN、容错CAN、LIN总线有什么区别?

大佬终于把鸿蒙OS讲明白了,收藏了!

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

当我们谈起C语言,很多人第一印象是面向底层、面向系统的编译型语言,写出来的程序一般都是从头到尾跑一遍就结束,很少和用户交互。但实际上,C语言从诞生开始就支持交互式的程序设计,通过标准输入输出和用户实时交互,接收用户输入、...

关键字: C语言 编程

在STM32嵌入式开发中,精确延时是非常基础但又极其关键的功能。无论是驱动单总线传感器(比如DS18B20)、控制LCD屏幕时序、还是生成精确的脉冲信号,都需要用到微秒级甚至纳秒级精度的延时。很多新手刚开始使用STM32...

关键字: STM32 嵌入式

在C语言开发中,位操作符是最容易被新手忽略,却能在嵌入式开发、底层驱动、算法优化中发挥巨大作用的工具。和常规的算术操作、逻辑操作相比,位操作直接操作二进制位,执行效率更高,占用代码空间更小,能轻松实现很多用常规方法很难实...

关键字: C语言 位操作符

在C语言开发中,原生字符串的使用一直存在诸多不便。传统C语言中,字符串本质是以'\0'结尾的固定字符数组,开发人员必须提前预估字符串的最大长度:如果预估过小,拼接或插入字符时会出现缓冲区溢出,引发内存越界错误;如果预估过...

关键字: C语言 字符串

随着半导体测试向更高复杂性与并行度演进,多工位自动测试设备(ATE)和SiC/GaN测试对电感、电容和电阻(LCR)测量的需求不断提升。然而,传统的外接台式LCR仪表和基于线缆的设置难以扩展,而且会降低可重复性。本文介绍...

关键字: 半导体 电阻 嵌入式

智能高尔夫球追踪系统是一项创新的嵌入式电子项目,旨在展示如何将紧凑型物联网硬件集成到体育科技应用中。在体育领域,高尔夫球扮演着主要角色,但在现代时代,所有设备都变得更加智能化,高尔夫球也由此演变为智能高尔夫球。本项目结合...

关键字: 嵌入式 物联网 NRF无线技术

在工业自动化、智能传感、嵌入式组网等分布式总线系统中,设备自动地址分配是实现节点互联互通、即插即用的核心技术。传统人工配置地址方式存在操作繁琐、扩展性差、地址冲突风险高、维护成本高等诸多问题,已无法适配大规模、动态化的总...

关键字: 总线 嵌入式 组网

2026年6月8日 – 专注于引入新品的全球电子元器件和工业自动化产品授权代理商贸泽电子 (Mouser Electronics) 正式宣布,首次荣获全球嵌入式应用安全连接解决方案知名供应商NXP® Semiconduc...

关键字: 物联网 移动设备 嵌入式

城市灯火通明、生活井然运转的背后,总有人在不被注意的地方,日复一日地坚持着。他们或许没有惊天动地的故事,却在漫长岁月里,用自己的方式守护着他人的生活。近日,乡村教师班爱花、爱心厨房运营者丫丫妈,以及“扛楼女工”云姐的故事...

关键字: 西门子家电 洗碗机 嵌入式

2026年5月15日,正值“世界无幽日”,一组数据再次引发公众关注:据《中国幽门螺杆菌感染防控》白皮书显示,我国幽门螺杆菌人群感染率已接近50%,涉及超过7亿人口,且家庭内传播特征极为显著——父母若感染,子女感染风险升高...

关键字: 洗碗机 AI 嵌入式
关闭