码迷,mamicode.com
首页 > 其他好文 > 详细

字符串处理函数

时间:2020-03-20 09:24:32      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:简单   获取   缓冲区   return   mic   字符串处理   strong   算法   strcmp   

 

1.  字符串输入

(1)gets   stdio.h

  技术图片    不安全的函数

char buf[20] = {0};
gets(buf);

  从标准输入获取一个字符串到s,遇到换行符就结束(不包括换行符,并在最后添加‘\0‘,然后存到s)

 

(2)fgets   stdio.h

  更安全的字符串输入

  技术图片

 

  最多读入size-1个字符串,还留了位置给‘\0‘

  fgets会将换行符读入  因此行8有必要

  返回值就是s指向缓冲区的地址

 1 #include <stdio.h>
 2 #include <string.h>
 3 
 4 int main ()
 5 {
 6     char buf[20] = {0};
 7     char *s = fgets(buf,20,stdin);
 8     buf[strlen(buf)-1] = \0;
 9     printf("**%s**",s);
10     return 0;
11 }

 

(3)fgetc  stdio.h

  读取一个字符,返回一个unsigned char

  技术图片

1 char c = fgetc(stdin);    //输入 ‘a‘
2 printf("**%c %d**",c,c);  //输入 ‘a‘  97

 

(4)getchar  stdio.h

  技术图片

 

 

2.  字符串输出

(1)fputs

  技术图片

 

  将s所指字符串输出到stream,不在最后添加换行符 

(2)puts

  技术图片

 

  输出s所指向的字符串到标准输出,并自动添加一个换行符

1 char buf[20] = {"**abc**"};
2 puts(buf);

 

  gets不保存换行符,puts自动添加换行符

  fgets保存换行符,fputs不自动添加换行符

 

(3)fgetc  stdio.h

  技术图片

 

  输出一个字符到stream

   

  

 

3. 字符串处理函数  <string.h>  ANSI C

(1)字符串长度

  技术图片

 

  返回不包括结尾的‘\0‘的字符串长度,单位字节 

  简单实现v1:

1 size_t my_strlen(const char *s)
2 {
3     assert(s != NULL);
4     size_t len = 0;
5     while(*(s++) != \0) {
6         ++len;
7     }
8     return len;
9 }

 

  简单实现v2:

1 size_t my_strlen(const char *s)
2 {
3     assert(s != NULL);
4     const char *pstr = s;
5     while(*(pstr++) != \0);
6     return pstr-s-1;
7 }

 

 

(2)字符串追加

  技术图片

 

  strcat的实现:

 1 char *my_strcat(char *dest,const char *src)
 2 {
 3     assert((dest != NULL) && (src != NULL));
 4     char *tmp = dest;
 5     while(*tmp != \0) {
 6         ++tmp;
 7     }
 8     while((*tmp++ = *src++) != \0);
 9     return dest;
10 }

 

  strncat:从src追加字符到dest后面,直到追加了 n个字符(n个字符不包括需要追加的‘\0‘,因此src需要再能容纳n+1个字符的空间)或者src结束了为止

  情况①:追加了n个字符,而src很长因此没到src的结尾‘\0‘处

  情况②:追加了n个字符,刚好src到了结尾‘\0‘处,即src有n个字符再加一个‘\0‘字符

  情况③:只追加了少于n个字符,src就到结尾了,对于这种情况,需要记得在dest结尾添加‘\0‘  行10~12

 1 char *my_strncat(char *dest,const char *src,size_t n)
 2 {
 3     assert((dest != NULL) && (src != NULL));
 4     int num = 0;
 5     char *tmp = dest;
 6     while(*tmp != \0) {
 7         ++tmp;
 8     }
 9     while((num++<n)&&(*tmp++ = *src++) != \0);
10     if(*(tmp-1) != \0) {
11         *tmp = \0;
12     }
13     return dest;
14 }

 

 

(3)字符串比较大小

  技术图片

  ①strcmp:按ASCII比较大小("abc" < "abcd") 

 1 int my_strcmp(const char* s1,const char* s2)
 2 {
 3     assert(s1 != NULL && s2 != NULL);
 4     while(*s1 == *s2) {
 5         if(*s1 == \0) {
 6             return 0;
 7         }
 8         ++s1;
 9         ++s2;
10     }
11     return ((*s1>*s2)?1:-1);
12 }

  ②glibc 2.23的strcmp实现

  感觉还没有上面的直观

 1 int my_strcmp2(const char *s1,const char *s2)
 2 {
 3     assert(s1 != NULL && s2 != NULL);
 4     const unsigned char *p1 = (const unsigned char *)s1;
 5     const unsigned char *p2 = (const unsigned char *)s2;
 6     unsigned char c1,c2;
 7     do {
 8         c1 = (unsigned char)*(p1++);
 9         c2 = (unsigned char)*(p2++);
10         if(c1 == \0 || c2 == \0) {
11             return c1 - c2;
12         }
13     }while(c1 == c2);
14     return (c1-c2);
15 }

 

  ③strncmp

  v1:类似①的写法,在while里加入条件

 1 int my_strncmp(const char *s1,const char *s2,size_t size)
 2 {
 3     assert(s1 != NULL && s2 != NULL && size > 0);
 4     while((*s1 == *s2)&&(--size > 0)) {  //--size的原因,在这里只比较size-1个字符,最后一个字符在最后的renturn里比较
 5         if(*s1 == \0) {
 6             return 0;
 7         }
 8         ++s1;
 9         ++s2;
10     }
11     //要么是*s1!=*s2,要么是size到0了
12     return (*s1 - *s2);
13 }

 

 

  v2:感觉差不多,可能有bug

 1 int my_strncmp2(const char *s1,const char *s2,size_t size)
 2 {
 3     assert(s1 != NULL && s2 != NULL && size > 0);
 4     while(--size>0) {
 5         if(*s1 == \0 || *s1 != *s2) {
 6             return (*s1 - *s2);
 7         }
 8         ++s1;
 9         ++s2;
10     }
11     return (*s1 - *s2);
12 }

 

 

(4)字符串复制

  技术图片

 

  ①strcpy

  类似于strcat,只是少了找dest结尾‘\0‘的环节,直接从dest一开始存储

1 char *my_strcpy(char *dest,const char *src)
2 {
3     assert((dest != NULL) && (src != NULL));
4     char *tmp = dest;
5     while((*tmp++ = *src++) != \0);
6     return dest;
7 }

  glibc里面:直接调用memcpy(dest,src,strlen(src)+1)

  ②strncpy

  一样,类似strncat,少了找dest结尾的环节

 1 char *my_strncpy(char *dest,const char *src,size_t n)
 2 {
 3     assert((dest != NULL) && (src != NULL));
 4     int num = 0;
 5     char *tmp = dest;
 6     while((num++<n)&&(*tmp++ = *src++) != \0);
 7     if(*(tmp-1) != \0) {
 8         *tmp = \0;
 9     }
10     return dest;
11 }

  glibc先调用memset将dest后面设为‘\0‘,再调用memcpy复制src字符过去

 

 

(5)字符串查找

  ①查找字符在字符串中第一次出现的位置

  技术图片

 

 

  

  ②查找字符在字符串中最后一次出现的位置

  技术图片

 

 

  ③查找字符串在字符串中第一次出现的位置------(KMP匹配算法

  技术图片

 

 

  ④查找字符串中任意一个字符在另一个字符串中第一次出现的位置

  技术图片

 

 

4.  stdio里的字符串操作

(1)输出到字符串(实际是字符数组)   

   技术图片

 

  类似C++的string流里面的ostringstream类(可将各种格式如整型数字、浮点写到字符串保存) 

(2)从字符串读

  技术图片

 

  类似C++的string流里面的istringstream类(可将字符串里的格式化数据如整型数字、浮点等读出来存到整型、浮点型变量,即实现字符串转数字)  

  简单例子:

1 char buf[20] = {"123 3.14"};
2 int a = 0;
3 double b = 0.0;
4 sscanf(buf,"%d %lf",&a,&b);
5 printf("a:%d\nb:%lf\n",a,b); //输出 123   3.140000

 

  tips:printf、scanf还有输出到文件流、从文件流读的相应的函数(C++有ifstream从文件流读、有ofstream向文件流写) 

  技术图片

 

  技术图片

 

 

 

5.  stdlib里面的字符串操作

(1)字符串转数字

  技术图片

 

 

6. 其它

 

      

 

字符串处理函数

标签:简单   获取   缓冲区   return   mic   字符串处理   strong   算法   strcmp   

原文地址:https://www.cnblogs.com/taoXiang/p/12521543.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!