C和指针:字符串

2024-09-08 14:36
文章标签 指针 字符串

本文主要是介绍C和指针:字符串,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

字符串、字符和字节

字符串基础

字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。

字符串长度就是字符串中字符数。

size_t strlen( char const *string );

string为指针常量(const修饰string),指向的string是常量不能修改。size_t是无符号数,定义在stddef.h。

#include <stddef.h>
size_t strlen( char const *string ){int length;for( length = 0;*string++!= '\0';)length += 1;return length;
}

C语言遍历字符串: while(*string++!='\0'){}

if(strlen(x)>=strlen(y))
if(strlen(x)-strlen(y)>=0)

上面两句不等价,第二个恒真,无符合数-无符合数还是无符合数,恒大于0。尽量不重写库函数,把时间花在程序其他部分的算法改进上,寻找一种更好的算法比改良一种差劲的算法更有效率,复用已经存在的软件比重新开发一个效率更高。

不受限制的字符串函数

"不受限制的字符串函数"指那些在处理字符串时不会自动检查目标缓冲区大小的函数。

这类函数通常依赖于字符串中的终止符( '\0')来确定字符串的结束位置,如strcpy, strcat等。

复制字符串
char *strcpy( char *dst, char const *src);

函数把参数 src 字符串复制到 dst 参数。如果参数 src和 dst在内存中出现重叠,结果是未定义的。由于 dst 参数将进行修改,所以它必须是个字符数组或者是一个指向动态分配内存的数组的指针,不能使用字符串常量。目标参数的以前内容将被覆盖并丢失。由于新字符串是以 NUL字节结尾,所以老字符串最后剩余的几个字符也会被有效地删除。

char message[] ="Original message"; 
if(... ) strcpy(message,"Different");

message是字符数组。

strcpy不能保证dst空间足够拷贝字符串。

char message[] = "Original message";
strcpy(message,"A different message");

第2个字符串太长了,无法容纳于message 字符数组中。strcpy 函数将侵占数组后面的部分内存空间,改写原先恰好存储在那里的变量。

连接字符串
char *strcat( char *dst, char const *src);

strcat 函数要求 dst 参数原先已经包含了一个字符串(可以是空字符串)。它找到这个字符串的末尾,并把 src字符串的一份拷贝添加到这个位置。如果src和 dst的位置发生重叠,其结果是未定义的。

strcpy(message,"Hello");
strcat(message,customer_name);
strcat(message,",how are you?" );

保证目标字符数组剩余的空间足以保存整个源字符串。

strcpy 和 strcat都返回它们第1个参数的一份拷贝,就是一个指向目标字符数组的指针。

字符串比较

比较两个字符串涉及对两个字符串对应的字符逐个进行比较,直到发现不匹配为止。那个最先

不匹配的字符中较“小”(字符集中的序数较小)的那个字符所在的字符串被认为“小

于”另外一个字符串。如果其中一个字符串是另外一个字符串的前面一部分,那么它也被认为“小

于”另外一个字符串,因为它的NUL结尾字节出现得更早(词典比较)。

int strcmp( char const *s1,char const *s2);

如果s1小于s2,strcmp 函数返回一个小于零的值。如果s1大于s2,函数返回一个大于零的值。

如果两个字符串相等,函数就返回零。

长度受限的字符串函数

这些函数接受一个显式的长度参数,用于限定进行复制或比较的字符数,防止长字符串从它们的目标数组溢出。

char *strncpy( char *dst, char const *src, size_t len);
char *strncat( char *dst, char const *src, size_t len);
int strncmp( char const *s1,char const *s2,size_t len);

如果源参数和目标参数发生重叠,strncpy 和 strncat的结果就是未定义。

和 strcpy 一样,strncpy 把源字符串的字符复制到目标数组。它总是正好向 dst写入 len个字符,如果strlen(src)的值小于len,dst数组就用额外的NUL字节填充len长度。如果 strlen(src)大于等于 len,只有len个字符被复制到dst中,结果不以 NUL字节结尾。

char buffer[BSIZE];
strncpy(buffer, name, BSIZE );
buffer[BSIZE-1]='\0';

在字符串最后手动添上'\0'。

  • strncat 总是在结果字符串后面添加一个NUL字节。
  • strncmp也用于比较两个字符串,但它最多比较 len个字节。如果两个字符串在第 len个字符之前存在不相等的字符,这个函数就像 strcmp 一样停止比较,返回结果。

字符串查找基础

查找一个字符

字符串中查找一个特定的字符

char* strchr( char const *str, int ch);
char* strrchr( char const *str, int ch ); 

strchr在字符串 str 中查找字符ch第1次出现的位置,找到后函数返回一个指向该位置的指针。如果该字符并不存在于字符串中,函数就返回一个NULL指针。

strrchr返回一个指向字符串中该字符最后一次出现的位置(最右边那个)。

查找任何几个字符
char *strpbrk( char const *str,char const *group);

返回一个指向 str 中第1个匹配group 中任何一个字符的字符位置。如果未找到匹配,函数返回一个NULL指针。 (任何几个:只要找到一个字符在group中即可)

查找一个子串
char *strstr( char const *s1, char const *s2 );

在s1中查找整个s2第1次出现的起始位置,并返回一个指向该位置的指针。如果s2并没有完整地出现在s1的任何地方,函数将返回一个NULL指针。如果第2个参数是一个空字符串,函数就返回s1。

高级字符串查找

strspn和 strcspn函数用于在字符串的起始位置对字符计数。

查找一个字符串前缀
size_t strspn( char const *str, char const *group);
size_t strcspn( char cosnt *str, char const *group );

strspn 函数计算从 str 开始直到遇到不属于 group 中的字符为止的字符数量。

strcspn 函数计算从 str 开始直到遇到属于 group 中的字符为止的字符数量。

查找标记
char *strtok( char *str, char const *sep);

解析由特定分隔符分隔的字符串。从字符串中隔离各个单独的称为标记(token)的部分,并丢弃分隔符。如果strtok 函数的第1个参数不是NULL,函数将找到字符串的第1个标记,strtok 同时将保存在字符串中的位置。如果strtok 函数的第1个参数是NULL,函数就在同一个字符串中从这个被保存的位置开始像前面一样查找下一个标记。如果字符串内不存在更多的标记,strtok 函数就返回一个NULL指针。

错误信息
char *strerror( int error_number );

strerror 函数把其中一个错误代码作为参数并返回一个指向用于描述错误的字符串的指针。

字符操作
字符分类

常用:isdigit、islower、isupper

字符转换
int tolower( int ch );
int toupper( int ch);

toupper 函数返回其参数的对应大写形式,tolower 函数返回其参数的对应小写形式。

如果函数的参数并不是一个处于适当大小写状态的字符,函数将不修改参数直接返回。

内存操作
void *memcpy( void *dst, void const *src, size_t length);
void *memmove( void *dst, void const *src, size_t length);
void *memcmp( void const *a, void const *b, size_t length);
void *memchr( void const *a, int ch, size_t length);
void *memset( void *a, int ch, size_t length);

memcpy 从src的起始位置复制 length个字节到 dst的内存起始位置。你可以用这种方法复制任何类型的值,第3个参数指定复制值的长度(以字节计)。如果src和 dst 以任何形式出现了重叠,结果是未定义的。前两个参数并不需要使用强制类型转换,因为在函数的原型中,参数的类型是 void*型指针,任何类型的指针都可以转换为void*型指针。

memmove函数的行为和 memcpy 差不多,只是源和目标操作数可以重叠。它不需要以下面这种方式实现,不过memmove 的结果和这种方法的结果相同,把源操作数复制到一个临时位置,临时位置不会与源或目标操作数重叠,再把它从这个临时位置复制到目标操作数。memmove 通常无法使用某些机器所提供的特殊的字节-字符串处理指令来实现,所以它可能比memcpy慢一些???

memcmp 对两段内存的内容进行比较,这两段内存分别起始于 a和b,共比较 length 个字节。

这些值按照无符号字符逐字节进行比较,函数的返回类型和 strcmp 函数一样——负值表示a小于b,

正值表示a大于b,零表示a等于b。

memchr从 a的起始位置开始查找字符ch第1次出现的位置,并返回一个指向该位置的指针,它共查找length个字节。如果在这length个字节中未找到该字符,函数就返回一个NULL指针。

memset函数把从 a开始的length个字节都设置为字符值ch。

这篇关于C和指针:字符串的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1148375

相关文章

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

PHP字符串全排列

方法一: $str = 'abc';$a =str_split($str);perm($a, 0, count($a)-1);function perm(&$ar, $k, $m) {if($k == $m){ echo join('',$ar), PHP_EOL;}else {for($i=$k; $i<=$m; $i++) {swap($ar[$k], $ar[$i]);perm($ar

PHP7扩展开发之字符串处理

前言 这次,我们来看看字符串在PHP扩展里面如何处理。 示例代码如下: <?phpfunction str_concat($prefix, $string) {$len = strlen($prefix);$substr = substr($string, 0, $len);if ($substr != $prefix) {return $prefix." ".$string;} else

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。

十一、C语言:字符串函数

目录 一、strlen 二、strcpy 三、strcat  四、strcmp 五、strstr 六、strtok 七、strerror 一、strlen 注意:strlen()函数的返回值是size_t,两个size_t相减仍为无符号数 int main(){char arr[10] = "abc";char brr[10] = "abc123";if (strl

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

C和指针:结构体(struct)和联合(union)

结构体和联合 结构体 结构体包含一些数据成员,每个成员可能具有不同的类型。 数组的元素长度相同,可以通过下标访问(转换为指针)。但是结构体的成员可能长度不同,所以不能用下标来访问它们。成员有自己的名字,可以通过名字访问成员。 结构声明 在声明结构时,必须列出它包含的所有成员。 struct tag {member-list} variable-list ; 定义一个结构体变量x(包含

NC 把数字翻译成字符串

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 有一种将字母编码成数字的方式:‘a’->1, ‘b->2’, … , ‘z->26’。 现在给一串数字,返回有多少种可能的译码结果 import java.u