C语言_10 字符、字符串操作

简介: 字符、字符串及一些函数

单字符输入输出

putchar(int c)函数:向标准输出写一个字符,但是输入是int类型,返回类型也是int 表示写了几个字符,一般为1,EOF(即:值-1)表示失败。(end of fail)
getchar():从标准输入读入一个字符,返回类型也是int(因为要返回EOF表示输入结束了)
写一个程序进一步理解。

int ch;
while((ch=getchar())!=EOF){
    putchar(ch);
}
printf("EOF\n");//这样来看读入什么会EOF
return 0;

不管怎么输入数字串、字符串都不停止,直到输入Ctrl-C,程序直接结束但没有看到EOF,这表示我们将程序强制结束了而不是正确的输入EOF。
第二次尝试输入Ctrl-D,得到输出EOF(Windows要输入Ctrl-Z)。而且另一件奇怪的事情是,即便输入12435435数字串,敲下回车之前都不会有回应,敲下回车后才原封不动地输出这一串。为什么?getchar()不是一个个读的吗?
原因:之前提到过中介shell,shell先处理输入的东西再给程序,输出的东西也先经过处理再呈现给我们。(当时在讲\b会变成什么样子)
用户(键盘等输入)→shell→程序
用户←shell←程序
shell对输入的东西做了行编辑,也就是敲下回车前输入的部分都在shell里处理,放在缓冲区里,按下回车后才送到程序那里。如:输入123,shell缓冲区里为“1,2,3,回车”。然后getchar()再读缓冲区。
如果按下Ctrl-D,shell会生成一个EOF的标志。而按下Ctrl-C,shell直接关闭了程序。
所以用户的输入是让shell填写缓冲区,而scanf()和getchar()都是在缓冲区内读。

字符串函数strlen

string.h头文件中处理字符串的函数比如:strlenstrcmpstrcpystrcatstrchrstrstr
strlen(const char*s):返回s的字符串长度(不包括结尾0)由参数表中的const可知该函数不会修改传入的数组。

char line[]="Hello";
printf("%lu\n%lu",strlen(line),sizeof(line));

输出结果:strlen=5,sizeof=6(结尾的0)
我们能不能写出一个strlen函数呢?
sizeof不行,因为我们得到的是指针所占据的大小。
我们需要遍历数组:H,e,l,l,o,\0
因为不知道数组有多大,用while循环。

int cnt=0;
while(s[cnt]!='\0'){
    cnt++;
}
return cnt;

字符串数组strcmp

int strcmp(const char*s1,const char*s2):比较两个字符串。

返回值 意义
0 相等
1 s1大
-1 s2大
大小是怎么定义的?
我们做一个尝试:
printf("%d\n",s1==s2);来判断s1和s2是否相等。
然而即便s1和s2内容相同还是输出了0.因为实际上s1==s2比较的是s1和s2的地址,所以数组之间的这种比较永远是0。
s1[]="abc";
s2[]="bbc";

再用strcmp比较两者输出了-1.这很合理,因为ASCII码b>a.

s1[]="abc";
s2[]="Abc";

输出32?32是'a'-'A'的结果。所以这回给出的结果是不相等的字符的差值。

s1[]="abc";
s2[]="abc ";//多了个空格

输出-32,是空格位\0-' '造成的。
接下来我们自己尝试写strcmp。我们需要下标idx,s1[idx]与s2[idx]比较,当s1[idx]和s2[idx]都=='\0'时停止(假设长度相等)。

while(s1[idx]!='\0'&&s1[idx]==s2[idx])//当出现不相等的字符或者字符串到了末尾时,返回差值
    idx++;
return s1[idx]-s2[idx];

改进:idx可不可以不用?
用指针:

*s1==*s2
s1++;
s2++;
return *s1-*s2;

这是处理字符串的两种手段,数组和指针。看个人喜好。

字符串函数strcpy

char*strcpy(char* restrict dst,char* restrict src);
把src拷贝到dst的空间里,包括结尾的\0.
restrict表示src和dst不能重叠。比如src是
H E L L O \0
,dst的内容是:
空 空 空 H E L L O \0
也就是说想把HELLO挪到第一位开始,这是不行的。因为strcpy对于多核计算机,为了提高效率,拷贝可能是交给不同的核不同的段,分别拷贝。
函数参数中的第一个参数是目的,而第二个参数是源。而且这个函数是有返回值的,返回dst

char *dst=(char*)malloc(strlen(src)+1);//不包含结尾的\0,所以+1
strcpy (dst,src);

+1是重点。
接下来尝试自己写strcpy()函数。

char *mycpy(char*dst,const char*src)
{
    int idx=0;
    while(src[idx]!='\0')
    {
        dst[idx]=src[idx];
        idx++;
    }
    dst[idx+1]='\0';
    return dst;

指针的做法是:

char *ret=dst;
while(*src!='\0')
{
    *dst=*src;
    *dst++;
    *src++;
}
*dst='\0';
return ret;

当然do-while也行.
也可以这样优化:

while(*src)*dst++ = *src++;

更艹的是,*dst++ = *src++;的结果就是*src,所以我们可以直接写

while(*dst++ = *src++);

字符串函数strcat

char*strcat(char* restrict s1,const char* restrict s2);
把s2拷贝到s1后面,接成一个长字符串;返回s1.(s1结尾的\0被s2开头替换掉)
如:s1: H E L L O \0

   s2:W O R L D\0

结果:s1: H E L L O W O R L D \0
s1必须要有足够的空间。
cpy和cat有可能没有足够的空间,因此这两个函数是不够安全的,不建议使用。
安全版本:strncpystrncat

char*strncpy(char* restrict s1,const char* restrict s2,size_t n);
char*strncat(char* restrict s1,const char* restrict s2,size_t n);
char*strncat(const char* s1,const char* s2,size_t n);

会拷贝能拷贝的最多的字符,多的部分掐掉。而strncmp则是只判断前几个字符。

字符串搜索函数

char* strchr(const char* s,int c);
char* strrchr(const char* s,int c);//从右边开始找
返回的是指针,返回NULL表示没找到。
那如果像HELLO出现两个L,怎样寻找第二个呢?

char *s="hello";
char *p=strchr(s,'l');
printf("%s",p);

输出llo。
想找第二个的方法是:

p=strchr(p+1,'l');

如果想把l后面的东西cpy到另一个字符串中去:

char *t=(char*)malloc(strlen(p)+1);
strcpy(t,p);
free(t);

如果我们想要l前面的部分?

char c=*p;
*p='\0';//把l的位置改成'\0'
char *t=(char*)malloc(strlen(s)+1);
strcpy(t,s);//只拷贝了第一个l前面的部分。

t就是想要的结果,即he
在字符串中找字符串:char* strchr(const char* s1,const char*s2);
不分大小写寻找:char* strcasestr(const char* s1,const char*s2);

目录
相关文章
|
1月前
|
存储 算法 C语言
【C语言】字符常量详解
字符常量是C语言中处理字符数据的重要工具。通过单引号括起一个字符,我们可以方便地使用字符常量进行字符判断、字符运算和字符串处理等操作。理解字符常量的表示方法、使用场景和ASCII码对应关系,对于编写高效的C语言程序至关重要。
189 11
|
1月前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
78 10
|
1月前
|
存储 C语言 开发者
【C语言】格式化输出占位符及其标志字符详解(基于ISO/IEC 9899:2024)
在C语言中,格式化输出通过 `printf` 函数等格式化输出函数来实现。格式说明符(占位符)定义了数据的输出方式,标准ISO/IEC 9899:2024(C23)对这些格式说明符进行了详细规定。本文将详细讲解格式说明符的组成部分,包括标志字符、宽度、精度、长度修饰符和类型字符,并适当增加表格说明。
48 6
|
2月前
|
存储 算法 C语言
C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项
本文深入探讨了C语言中常见的字符串处理技巧,包括字符串的定义、初始化、输入输出、长度计算、比较、查找与替换、拼接、截取、转换、遍历及注意事项,并通过案例分析展示了实际应用,旨在帮助读者提高编程效率和代码质量。
147 4
|
3月前
|
C语言
C语言字符(串)函数
C语言字符(串)函数
|
3月前
|
C语言 C++
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
【C语言】解决不同场景字符串问题:巧妙运用字符串函数
|
3月前
|
存储 安全 编译器
深入C语言库:字符与字符串函数模拟实现
深入C语言库:字符与字符串函数模拟实现
|
4月前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]="hello"`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
134 8
|
4月前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
286 7
|
3月前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲

热门文章

最新文章