你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C语言字符串操作

[复制链接]
gaosmile 发布时间:2020-12-17 23:22
#字符串倒序输出

实现逻辑,通过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;
  str = 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 = '\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--->str:h
dst:l--->str:h
dst--->str:h
dst:,--->str:h
dst:w--->str:h
dst--->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字符所覆盖。


收藏 评论0 发布时间:2020-12-17 23:22

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版