详解字符函数和字符串函数-1

简介: 详解字符函数和字符串函数

一. 字符分类函数

C语⾔中有⼀系列的函数是专⻔做字符分类的,也就是⼀个字符是属于什么类型的字符的。

这些函数的使⽤都需要包含⼀个头⽂件是 ctype.h

06a932f8d91412241b6b58bde2e8089a_b95531cab0c4450090fa10c917cf0481.png


这些函数的使⽤⽅法⾮常类似,我们就讲解⼀个函数的事情,其他的⾮常类似:


int islower ( int c );

islower 是能够判断参数部分的c是否是⼩写字⺟的。

通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回 0。


1.1 练习:将字符串小写转换成大写

思路:小写字母ASCII值大于大写字母ASCII值32.

#include <stdio.h>
#include <ctype.h>
int main()
{
  int i = 0;
  char str[] = "i am a student.";
  while (str[i])
  {
  if (islower(str[i]))
    str[i] = str[i] - 32;
  i++;
  }
  printf("%s", str);
  return 0;
}


输出:


0e2a1a665826364b34bf34f177ee3c71_ef3942333d6744afb0a24135844a99c3.png


二、 字符转换函数

C语⾔提供了2个字符转换函数:

int tolower ( int c ); //将参数传进去的大写字⺟转小写
int toupper ( int c ); //将参数传进去的小写字⺟转大写


2.1 练习:将字符串小写转换成大写

思路:

上面的代码,我们将小写转大写,是-32完成的效果,有了转换函数,就可以直接使⽤ toupper  函数。

#include <stdio.h>
#include <ctype.h>
int main()
{
  int i = 0;
  char str[] = "i am a student.";
  while (str[i])
  {
  if (islower(str[i]))
    str[i] = toupper(str[i]);
  i++;
  }
  printf("%s", str);
  return 0;
  return 0;
}


三. strlen的使用和模拟实现

size_t strlen ( const char * str );

3.1 strlen的注意事项

• 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前⾯出现的字符个数(不包

含 '\0' )。

• 参数指向的字符串必须要以 '\0' 结束。

• 注意函数的返回值为size_t,是无符号的( 易错考点 )

易错考点:


#include <stdio.h>
int main()
{
  const char* str1 = "abcdef";
  const char* str2 = "bbb";
  if (strlen(str2) - strlen(str1) > 0)
  {
  printf("str2>str1\n");
  }
  else
  {
  printf("srt1>str2\n");
  }
  return 0;
}

输出:561e0c178bba9eb3b573018668c47d90_844c62207fc3421a8fee6f90ec24a0c8.png


解析: strlen(str2) - strlen(str1) > 0,strlen的返回类型是无符号整型,无符号整型-无符号整型还是无符号整型,-3的补码当成正数看是一个非常大的正数


3.2 strlen函数的模拟实现

方式1:

//计数器⽅式
size_t my_strlen(const char * str)
{
int count = 0;
assert(str);
while(*str)
{
count++;
str++;
}
return count;
}

方式2:


//指针-指针的⽅式==中间元素个数
size_t my_strlen(char *s)
{
 assert(str);//保证指针的安全性
 char *p = s;
 while(*p != ‘\0’ )
 {
 p++;
}
 return p-s;
}
方式3:
//递归
size_t my_strlen(const char * str)
{
 assert(str);
 if(*str == '\0')
 return 0;
 else
 return 1+my_strlen(str+1);
}

值得注意的是return 1+my_strlen(str+1);这里的str+1不能改成str++,因为str++是先用后++,每次都是传str的地址,导致死循环。


四. strcpy的使用和模拟实现

char* strcpy(char * destination, const char * source );

Copies the C string pointed by source into the array pointed by destination, including the


terminating null character (and stopping at that point).

将source指向的字符串copy到destination指向的空间,包括源字符串的‘0’也会被copy进去。

返回值是目标空间的起始地址。


4.1  strcpy的注意事项

• 源字符串必须以 '\0' 结束。

• 会将源字符串中的 '\0' 拷⻉到⽬标空间。

• ⽬标空间必须⾜够⼤,以确保能存放源字符串。

• ⽬标空间必须可变。


4.2 strcpy的模拟实现

char *my_strcpy(char *dest, const char*src)
{ 
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}


五. strcat的使用和模拟实现

char * strcat(char*destination,const char*source)

Appends a copy of the source string to the destination string. The terminating null character


in destination is overwritten by the first character of source, and a null-character is included

at the end of the new string formed by the concatenation of both in destination.

源字符串追加copy到目标字符串,源字符串的第一个字符覆盖目标字符串的最后'\0'字符,追加copy内容一直包括源字符串的'\0'字符。


5.1 strcat的注意事项

• 源字符串必须以 '\0' 结束。

• ⽬标字符串中也得有 ‘0’  ,否则没办法知道追加从哪⾥开始。

• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。

• ⽬标空间必须可修改。


问题:自己追加拼接自己可以吗?


int main()
{
  char s[20] = "hellow";
  char*p=strcat(s, s);
  printf("%s", s);
  return 0;
}

输出:


6591d31a81b99f9d78c689f9f4b1ab85_68d0750323594135ac9a4a53b9e76243.png


答案:不可以!因为追加拼接的时候会覆盖s的‘\0’,导致会无限 拼接,会使目标数组越界访问。


5.2 strcat的模拟实现

char *my_strcat(char *dest, const char*src)
{
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while(*dest)
 {
 dest++;
}
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}


六. strcmp 的使用和模拟实现

int strcmp(const char*str1,const char*str2)

This function starts comparing the first character of each string. If they are equal to each


other, it continues with the following pairs until the characters differ or until a terminating

null-character is reached.

函数比较俩个字符串大小

函数开始比较俩个字符串第一个字符,若俩个字符相等,按顺序依次比较接下来对应位置字符,直到字符不同或者到‘\0’字符结束。


• 标准规定:

◦ 第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字

◦ 第⼀个字符串等于第⼆个字符串,则返回0

◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字

◦ 那么如何判断两个字符串?  比较两个字符串中对应位置上字符ASCII码值的大小。

6.1 strcmp函数的模拟实现

int my_strcmp (const char * str1, const char * str2)
{
int ret = 0 ;
assert(src != NULL);
assert(dest != NULL);
while(*str1 == *str2)
{
if(*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1-*str2;
}


七. strncpy 函数的使用和模拟实现

char * strncpy ( char* destination, const char * source, size_t num );

• 拷⻉num个字符从源字符串到⽬标空间。


• 如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。

7.1 strncpy的模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* dest, const char* src, size_t num)
{
  char* ret = dest;
  assert(dest);
  assert(src); int i = 0;
  while (i < num && *src != '\0')
  {
  *dest++ = *src++;
  i++;
  }
  if (i == num)
  {
  return ret;
  }
  else
  {
  while (i < num)
  {
    *dest = '\0';
    dest++;
    i++;
  }
  return ret;
  }
}
int main()
{
  char arr1[10] = "xxxxxxxxx";
  char arr2[] = "ab";
  char* ret = my_strncpy(arr1, arr2, 5);
  printf("%s\n", ret);
  return 0;
}


b0a16f07e99dade23e3625b56395030e_3d16453d567f49ffa27578002dc4eb77.png


通过调试发现,少于num的位置用'\0'补齐。

相关文章
|
2月前
字符串函数
字符串函数
|
4月前
|
C语言
字符函数和字符串函数
字符函数和字符串函数
51 0
|
5月前
|
C语言
字符函数和字符串函数(上)
字符函数和字符串函数
|
5月前
|
C语言
字符函数和字符串函数(下)
字符函数和字符串函数(下)
|
5月前
|
C语言
详解字符函数和字符串函数-2
详解字符函数和字符串函数
26 0
|
6月前
|
编译器
C详细的字符串函数
C详细的字符串函数
33 0
|
7月前
|
编译器 C语言 Python
字符函数和字符串函数(上)
字符函数和字符串函数(上)
30 0
|
7月前
|
C语言 Python
字符函数和字符串函数(下)
字符函数和字符串函数(下)
27 0
字符函数和字符串函数(下)
|
8月前
|
存储 安全
常用的字符函数和字符串函数
常用的字符函数和字符串函数
66 0
|
9月前
|
C语言
字符函数和字符串函数详解(一)
字符函数和字符串函数详解
29 0