前言

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 中或者 字符数组 中。下面介绍C语言中的一些常用的字符串函数和内存函数的功能以及实现原理。

字符串函数(包含在头文件string.h)

strlen

函数声明

size_t strlen ( const char * str );

注:size_t类型其实就是unsigned long long类型

函数的功能

返回str指向的字符串长度,从str指向的字符算起,一直到字符串末尾的\0结束,如果没有\0,函数将继续增加str长度知道遇到\0为止。

使用案例

/* strlen example */
#include <stdio.h>
#include <string.h>int main ()
{char szInput[256];printf ("Enter a sentence: ");gets (szInput);//读取字符串printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));return 0;
}

输出结果为:
Enter sentence: just testing
The sentence entered is 12 characters long.

strcpy

函数声明

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

函数功能

把字符串source拷贝到字符串destination中,从source指向的位置开始拷贝直到遇到\0,并把\0拷贝到destination字符串中。使用此函数要注意为字符串destination分配的空间要大于为source字符串分配的空间,否则会越界访问报错。

注意事项

源字符串必须以 ‘\0’ 结束。
会将源字符串中的 ‘\0’ 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。

使用案例

/* strcpy example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[]="Sample string";char str2[40];char str3[40];strcpy (str2,str1);strcpy (str3,"copy successful");printf ("str1: %s\nstr2: %s\nstr3: %s\n",str1,str2,str3);return 0;
}

输出结果为:
str1: Sample string
str2: Sample string
str3: copy successful

strcat

函数声明

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

函数功能

把source字符串接到destination字符串后,destination字符串末尾的\0会被覆盖,source字符串包括其末尾的\0都会被拷贝到destination字符串末尾。

注意事项

源字符串必须以 ‘\0’ 结束。
目标空间必须有足够的大,能容纳下源字符串的内容。
目标空间必须可修改。

使用案例

/* strcat example */
#include <stdio.h>
#include <string.h>int main ()
{char str[80];strcpy (str,"these ");strcat (str,"strings ");strcat (str,"are ");strcat (str,"concatenated.");puts (str);return 0;
}

输出结果为:
these strings are concatenated.

strcmp

函数声明

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

函数功能

函数从两字符串开头开始,按照每个字符的ASCII码大小向后一一比较每个字符,直到遇到不相等的字符或是遇到\0结束。如果遇到不相等的字符时str1中的字符ASCII码大于str2中的,函数返回一个正整数,如果小于,函数返回一个负整数。如果两字符串中的每个字符都相同,函数返回0。

使用案例

//猜水果游戏
#include <stdio.h>
#include <string.h>int main ()
{char key[] = "apple";char buffer[80];do {printf ("Guess my favorite fruit? ");scanf ("%79s",buffer);} while (strcmp (key,buffer) != 0);//猜错了就继续猜,猜对了才退出循环puts ("Correct answer!");return 0;
}

strncpy

函数声明

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

函数功能

把source指向的字符串的前num个字节复制给destination指向的num个字节,如果source字符串本身并没有num那么长,那么复制的时候会把不够的地方用0补上,0是\0的ASCII码值,也就是说不够的地方复制的是\0。destination和source参数所指向的数组的大小至少应该是num字节,并且不应该重叠(对于重叠的内存块,memmove是一个更安全的方法)。

使用案例

/* strncpy example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[]= "To be or not to be";char str2[40];char str3[40];/* copy to sized buffer (overflow safe): */strncpy ( str2, str1, sizeof(str2) );/* partial copy (only 5 chars): */strncpy ( str3, str2, 5 );str3[5] = '\0';   /* null character manually added */puts (str1);puts (str2);puts (str3);return 0;
}

Output:

To be or not to be
To be or not to be
To be

strncat

函数声明

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

函数功能

把source字符串的前num个字节接到destination字符串后,destination字符串末尾的\0会被覆盖,source字符串接好后在最末尾加上\0,如果source中的C字符串长度小于num,则只复制到空字符结束之前的内容。

使用案例

/* strncat example */
#include <stdio.h>
#include <string.h>int main ()
{char str1[20];char str2[20];strcpy (str1,"To be ");strcpy (str2,"or not to be");strncat (str1, str2, 6);puts (str1);return 0;
}

Output:

To be or not

strncmp

函数声明

int strncmp ( const char * str1, const char * str2, size_t num );

函数功能

比较C字符串stri和C字符串str2的num字符。这个函数开始比较每个字符串的第一个字符。如果它们相等,则继续执行下面的一对字符,直到字符不同,直到达到一个结束的空字符,或直到两个字符串中的num字符匹配,以先发生的为准。如果比较过程中str1的字符大于对应的str2的字符则返回大于0的整数,如果全部相同返回0,如果比较过程中str1的字符小于于对应的str2的字符则返回小于0的整数,这里比较原则是根据字符的ASCII码大小比较的。

使用案例

/* strncmp example */
#include <stdio.h>
#include <string.h>int main ()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts ("Looking for R2 astromech droids...");for (n=0 ; n<3 ; n++)//str[n]是二维数组第n+1行的地址或是理解为第n+1行字符串名或者地址if (strncmp (str[n],"R2xx",2) == 0){printf ("found %s\n",str[n]);}return 0;
}

Output:

Looking for R2 astromech droids…
found R2D2
found R2A6

strstr

函数声明

char * strstr ( const char *str1, const char * str2);

函数功能

在str1字符串中匹配查找字符串str2,如果str2是str1的子串则函数返回str2第一次出现在str1中的地址,如果str2不是str1的子串则返回NULL。在匹配过程中不包括字符串的结束标志\0。

使用案例

/* strstr example */
#include <stdio.h>
#include <string.h>int main ()
{char str[] ="This is a simple string";char * pch;pch = strstr (str,"simple");//pch指向str中simple的sif (pch != NULL)strncpy (pch,"sample",6);puts (str);return 0;
}

Output:

This is a sample string

strtok

注:此函数比较难用,要想掌握此函数,必须多次使用而且掌握函数的实现原理。

函数声明

char * strtok ( char * str, const char * sep );

函数功能

扫描一个字符串str,若在str中遇到字符串sep的任意子串,则把str中对应的子串
的第一位替换为\0,并返回扫描开始位置的地址。

函数实现原理

这个函数中有一个静态全局变量(假设为p),p是保存扫描的开始地址,如果str为字符串首地址,那么p就会被赋值为str,如果str为空,p的值为上次调用完成后p保存的值。从p位置开始向后扫描,如果遇到sep的子串,函数会把str中对应的子串的第一位置为\0,p保存这个str中这个子串的后一位地址,并返回扫描开始的地址,如果一直扫描到|\0也没遇到sep的子串,那返回值为NULL。stroke函数会改变str字符串的内容,若不想改变,则需新建立一个内容相同的字符串。

使用案例

/* strtok example */
#include <stdio.h>
#include <string.h>int main ()
{char str[] ="- This, a sample string.";char * pch;printf ("Splitting string \"%s\" into tokens:\n",str);pch = strtok (str," ,.-");while (pch != NULL){printf ("%s\n",pch);pch = strtok (NULL, " ,.-");}return 0;
}

Output:

Splitting string “- This, a sample string.” into tokens:
This
a
sample
string

字符分类函数(包含在头文件ctype.h)

这些函数的声明的格式都是:int 函数名(int c)
参数c可以是要判断的字符c,也可以是c的ASCII码。

内存函数(包含在头文件string.h)

memcpy

函数声明

void * memcpy ( void * destination, const void * source, size_t num );

函数功能

将num字节的值从source指向的位置直接复制到destination指向的内存块。source指针和destination指针所指向的对象的基础类型与此函数无关;结果是数据的二进制拷贝。该函数不检查源文件中是否有任何终止空字符——它总是精确地复制num字节。为了避免溢出,destination和source参数所指向的数组的大小至少应该是num字节,并且不应该重叠(对于重叠的内存块,memmove是一个更安全的方法)。函数返回的是void*类型的destination保存的值,若需要使用此函数的返回值则需要进行相应的类型转换。

使用案例

/* memcpy example */
#include <stdio.h>
#include <string.h>struct {char name[40];int age;
} person, person_copy;int main ()
{char myname[] = "Pierre de Fermat";/* using memcpy to copy string: */memcpy ( person.name, myname, strlen(myname)+1 );person.age = 46;/* using memcpy to copy structure: */memcpy ( &person_copy, &person, sizeof(person) );printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );return 0;
}

Output:

person_copy: Pierre de Fermat, 46

memmove

函数声明

void * memmove ( void * destination, const void * source, size_t num );

函数功能

移动内存块将num字节的值从source所指向的位置复制到destination所指向的内存块。复制就像使用了中间缓冲区一样,允许destination和source重叠。source指针和destination指针所指向的对象的基础类型与此函数无关;结果是数据的二进制拷贝。该函数不检查源文件中是否有任何终止空字符——它总是精确地复制num字节。为了避免溢出,目标参数和源参数所指向的数组的大小应至少为num字节。

使用案例

/* memmove example */
#include <stdio.h>
#include <string.h>int main ()
{char str[] = "memmove can be very useful......";memmove (str+20,str+15,11);puts (str);return 0;
}

Output:

memmove can be very very useful.

注:到这里认真的你应该会发现,memmove、strncpy和memcpy三个函数在对字符串的使用中具有差不多的作用

memcmp

函数声明

int memcmp ( const void * ptr1,  const void * ptr2,  size_t num );

函数功能

比较两个内存块将ptri指向的内存块的第一个num个字节与ptr2指向的第一个num个字节进行比较;如果在两个内存块中不匹配的第一个字节在ptr1中的值比在ptr2中的值低(如果计算为unsigned char值)返回一个负整数,如果两个内存块的内容是相等的返回0,如果在两个内存块中不匹配的第一个字节在ptr1中的值大于ptr2中的值(如果计算为unsigned char值)返回一个正整数。注意,与strcmp不同,该函数在找到空字符后不会停止比较。

使用案例

/* memcmp example */
#include <stdio.h>
#include <string.h>int main ()
{char buffer1[] = "DWgaOtP12df0";char buffer2[] = "DWGAOTP12DF0";int n;n=memcmp ( buffer1, buffer2, sizeof(buffer1) );if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);return 0;
}

Output:

‘DWgaOtP12df0’ is greater than ‘DWGAOTP12DF0’.

C语言常见字符串函数、字符分类函数与内存函数的使用相关推荐

  1. c语言字符串操作面试题,C语言常见字符串面试题.pdf

    C语言常见字符串面试题 1. 字符串库函数的内部实现 memset库函数的实现 /* * memset - Fill a region of memory with the given value * ...

  2. python中怎么统计英文字符的个数_python怎样实现字符串中字符分类及个数统计

    python怎样实现字符串中字符分类及个数统计 发布时间:2020-11-20 17:31:18 来源:亿速云 阅读:105 作者:小新 小编给大家分享一下python怎样实现字符串中字符分类及个数统 ...

  3. C语言中字符串和字符数组的区别

    C语言中字符串和字符数组的区别 1.基本概念 2.代码分析 3.总结 1.基本概念 字符串和字符数组很相似,但是有本质上的区别. (1) C语言中,字符串是双引号括起来的单个或多个字符的集合,编译器自 ...

  4. C++语言篇 字符串及字符数组练习

    01:统计数字字符个数 描述 输入一行字符,统计出其中数字字符的个数. 输入 一行字符串,总长度不超过255. 输出 输出为1行,输出字符串里面数字字符的个数. 样例输入 Peking Univers ...

  5. C语言|统计字符串中英文字符个数

    Q:调用函数,统计字符串中英文字符个数 A: 思想:定义一个变量count,遍历字符串,判断每个字符的ASCII码值是否为'a'到'z'和'A'到'Z'之间的字母,若在此范围之间则记录数量,count ...

  6. c语言出现开头结尾多空格,C语言除去字符串开头和末尾空格之trim()函数的实现...

    Trim()函数功能除去字符串开头和末尾的空格或其他字符,函数执行成功时返回删除了字符串首部和尾部空格的字符串. char *trim(char *str) C语言标准库中并没有trim()函数,比较 ...

  7. 2. Python函数式编程中的字符串,元组,函数的分类,高阶函数,一篇文章都介绍一遍

    函数式编程中的字符串 在函数式编程中,经常用到 Python 字符串,因其是不可变数据结构. 字符串本身是一个对象,具备很多对象方法,与常识中函数的使用不太相同,例如下述代码 my_str = &qu ...

  8. C语言常见字符串处理string.h库函数strstr、strchr、strcat、strcmp、strcpy、strlen的介绍

    目录 strstr 声明 返回值 strchar 声明 返回值 strchr和strstr的差别 strcat 声明 返回值 strcmp 声明 返回值 strcpy 声明 返回值 strlen 声明 ...

  9. matlab 判断数据类型函数,matlab 分类(判别)函数classify()

    在生产.科学研究和日常生活中,经常会遇到对某一研究对象属于哪种情况作出 判断.例如要根据这两天天气情况判断明天是否会下雨:医生要根据病人的体温.白血 球数目及其它症状判断此病人是否会患某种疾病等等. ...

最新文章

  1. 数据库和缓存一致性的问题
  2. 后盾网php多少钱_复合排水网价格多少钱
  3. iOS 下配置XMPP 服务器openfire详解
  4. 用coffee和socket.io实现的01背包算法
  5. 查询oracle sql语句执行最慢和执行最多的语句!
  6. LVDS 相关功能调式
  7. 计算机期末考试操作题简单,计算机期末考试操作题及答案计算机期末考试操作题及答案.doc...
  8. 大内存 php 干什么好 centos,解决CentOS7中php-fpm进程数过多导致服务器内存资源消耗较大的问题...
  9. 刚刚,“国民”APP微信崩了!官方致歉:已经逐步恢复
  10. php 后端刷新页面
  11. java synchronized讨论
  12. ubuntu下载goalng-1.9
  13. 创业团队如何与兼职做饭的阿姨结算工资比较好?
  14. 几个值得收藏windows软件
  15. 语音社交APP系统开发,提供纯粹的语音社交
  16. fragment中文网_Fragment基本概述
  17. 区块链网络性能的关键衡量指标
  18. 时间序列学习 经典案例(3)离散傅里叶变换DFT(案例:时序去噪)
  19. 对LMAX架构以及Event Sourcing模式的一些新思考和问题的记录
  20. ElementUI表格中显示图片,悬浮显示放大图片

热门文章

  1. plotly绘制简单图形10--金字塔图
  2. 后来的我们都老了——看《后来的我们》
  3. 前端教程:用 Canvas 编织璀璨星空图
  4. Ubuntu 18.04.1 LTS 安装网易云音乐,告别图标无法点击
  5. 计算机机房管理具体工作和职责,机房职责_机房岗位职责_机房工作职责
  6. 电商平台关联法则模型及推荐系统实现(R语言)
  7. 美国圣诞8日西海岸自驾游
  8. Git 和 GitHub 快速入门
  9. python中转义是什么意思_python中的转义
  10. 汽配供应链管理系统:助力汽配企业实现采购业务全过程数字化管理