一,字符串函数说明
1,C语言里所有文字信息必须存储在一组连续的字符类型存储区里,所有文字信息必须以'\0'作为结尾,这个字符的ASCII码就是数字0,符合这两个特征的内容叫字符串。C语言里使用字符串记录文字信息,字符串里'\0'字符前面的内容才是有效字符,所有字符串一定可以使用字符指针表示。
2,字符串字面值是表示字符串的一种方式,例如"abc","^%&"。编译器在编译的时候会自动在字符串字面值后加上'\0'字符,编译器会使用第一个字符所在存储区的地址替换掉字符串字面值,字符串字面值里的内容在程序执行过程中不可以改变。如果程序中使用多个内容一样的字符串字面值,它们其实是同一个,它们所占的内存一样。如果多个字符串字面值并列写在一起则编译器会把它们合并成一个字符串字面值
3,字符数组也可以表示字符串。只有包含'\0'字符的字符数组才可以代表字符串,可以用字符串字面值对字符数组进行初始化,这个时候'\0'字符也会被初始化到字符数组里去。使用字符串字面值对字符数组初始化完以后它们的存储区之间就没有关系了。字符数组里字符串内容可以修改,可以在printf函数里使用%s作为占位符把字符串打印在屏幕上。不可以使用操作符对字符串进行操作。
二,字符串函数:头文件string.h
1,strlen 统计字符串里有效字符个数与sizeof完全不同
2,strcat 合并两个字符串这个函数有可能造成数组越界,由此导致严重问题
strncat 功能和strcat类似,但是可以避免出问题
3,strcmp 用来比较两个字符串大小
返回值为1表示前一个字符串大;返回值为-1表示后一个字符串大;返回值为0表示一样大。
strncmp 比较两个字符串中前n个字符
4,strcpy把一个字符串的内容复制到一个字符数组里这个函数也可能造成数组越界严重问题
strncpy 可以只复制字符串中前n个字符
5,memset 把字符数组里多个连续的存储区内容设置成同一个字符
6,strstr 可以在一个字符串里查找一个小字符串的位置,返回值是找到的小字符串里第一个字符存储区的地址,如果没有找到则返回值是NULL。
7,其他与字符串有关的函数
sprintf 把多个数据按格式打印在字符数组里形成字符串
sscanf 从字符串中获得多个数字并记录到变量存储区里
8,其他和字符串有关的函数,为了使用这两个函数需要包含stdlib.h头文件
atoi 可以把字符串里的整数转换成整数类型
atof 可以把字符串里的浮点数转换成双精度浮点类型
可以在scanf函数调用语句中使用%s作为占位符把键盘输入的字符串记录到字符数组里,这可能造 成严重错误。
9,fgets函数也可以从键盘得到一个字符串并记录到数组里,这个函数可以避免scanf函数的问题,函数三个参数(1).数组名称(2)数组里存储区个数(3)用stdin表示键盘。如果输入内容不能填满数组则会把最后输入的'\n'也放在数组里,如果输入内容过多则多余的内容留给下次读取。每次使用fgets函数从键盘得到字符串后都应该清理可能存在的垃圾数据,清理垃圾数据的语句应该放在一个分支里。
10,strtok:分离分隔符
(1)sep参数是个字符串,定义了用作分隔符的字符集合;
(2)第一个参数指定一个字符串,它包含了0个或者多个sep字符串中一个或者多个分隔符分割的标记;
(3)strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针;(strtok函数会改变被操作的字符串,所以在使用strtok切分的字符串一般都是临时拷贝的内容并且可以被修改);
(4)strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置;
(5)strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始查找下一个标记;如果字符串中不存在更多的标记则会返回NULL指针。
例1
#include<stdio.h>
#include<string.h>
int main()
{
char str[20]="asdfghjkl";
printf("strlen(str)=%d,sizeof(str)=%d\n",strlen(str),sizeof(str));
strcat(str,"rst");
printf("str=%s\n",str);
strncat(str,"hhhhhhhhhkkkkkkk",1);
printf("str=%s\n",str);
printf("比较结果是%d\n", strcmp("abc", "abd"));
printf("str=%s\n", strcpy(str, "abcdxyz"));
printf("str=%s\n",strncpy(str,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhkkkkkkk",18));
memset(str, 't', 10);
printf("str=%s\n",str);
printf("----------------------------\n");
printf("%s\n", strstr("abcdefxyz", "cde"));
printf("%d\n", strstr("abcdefxyz", "cdk"));
printf("%d\n", strstr("xyz", "cde"));
printf("%s\n", strstr("mmmxyz", "mmxyz"));
}
例2
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[20] = {0};
char ch = 0;
int num = 0;
float fnum = 0.0f;
printf("%d %c %g\n", 34, 'u', 4.2f);
sprintf(str, "%d %c %g", 34, 'u', 4.2f);
printf("%s\n", str);
printf("-------------------\n");
sscanf(str, "%d %c %g", &num, &ch, &fnum);
printf("ch是%c,num是%d,fnum是%g\n", ch, num, fnum);
printf("%d\n", atoi("34sdg214"));
printf("%lg\n", atof("34.23asd34"));
char my[40]="zhangsan 1998 85.5hhhkkk";
char name[14];
int birth;
double score;
sscanf(my, "%s %d %lg", &name, &birth, &score);
printf("name=%s,birth=%d,score=%lg\n",name,birth,score);
printf("-------------------\n");
char arr[10]={0};
printf("input a data:\n");
//scanf("%s",arr);
fgets(arr,10,stdin);
if(strlen(arr)==9&&arr[8]!='\n')
{
scanf("%*[^\n]");
scanf("%*c");
}
printf("%s\n",arr);
return 0;
}
三,使用指针实现字符串函数
1,strtok
#include <string.h>
int strtok_public()
{
char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";
char *delim = "-: ";
char *p;
printf("%s ", strtok(s, delim));
while((p = strtok(NULL, delim)))
{
printf("%s ", p);
}
printf("\n");
return 0;
}
//执行结果为:ab cd ef;gh i jkl;mnop;qrs tu vwx y;z 。
//自己实现strtok函数:
#include<stdio.h>
//该程序的关键点在于定义了一个静态的字符指针,该指针用来记录分割后的字符串的首地址
//传入NULL,则表示继续处理静态指针指向的余下字符串
char *strtok(char *str, const char *delim)
{
static char *src=NULL;//记下上一次非分隔字符串字符的位置,详见图示
const char *indelim=delim; //对delim做一个备份
int flag=1,index=0;
//每一次调用strtok,flag标记都会使得程序只记录下第一个非分隔符的位置,以后出现非分隔符不再处理
char *temp=NULL; //程序的返回值
if(str==NULL)
{
str=src; //若str为NULL则表示该程序继续处理上一次余下的字符串
}
for(;*str;str++)
{
delim=indelim;
for(;*delim;delim++)
{
if(*str==*delim)
{
*str='\0';//若找到delim中感兴趣的字符,将该字符置为NULL
index=1; //用来标记已出现感兴趣字符
break;
}
}
if(*str != '\0' && flag==1)
{
temp=str; //只记录下当前第一个非感兴趣字符的位置
flag=0;
}
if(*str != '\0' && flag==0 && index==1)
{
src=str; //第二次出现非感兴趣字符的位置(之前一定出现过感兴趣字符)
return temp;
}
}
src=str;//执行该句表明一直未出现过感兴趣字符,或者说在出现了感兴趣的字符后,就没再出现过非感兴趣字符
return temp;
}
int main()
{
char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";
char *delim = "-: ";
char *p;
printf("%s ", strtok(s, delim));
while((p = strtok(NULL, delim) ))
{
printf("%s ", p);
printf("\n");
}
return0;
}
2,strcpy
//字符串练习:实现strcpy的拷贝功能char
#include<stdio.h>
/*char *mystrcpy(char *p_dest,const char *p_src)
{
char *p_dest_m=p_dest;
const char *p_src_m=p_src;
while(*p_src_m)
{
*p_dest_m=*p_src_m;
p_src_m++;
p_dest_m++;
}
*p_dest_m=0;
return p_dest;
}*/
char *mystrcpy(char *p_dest,const char *p_src)
{
while(*p_src)
{
*p_dest=*p_src;
*p_dest++;
*p_src++;
}
return p_dest;
}
char* my_strncpy(char* str1, char* str2, size_t n)
{
char* ret = str1;
while (n)
{
*str1 = *str2;
str1++;
str2++;
n--;
}
return ret;
}
int main()
{
char str[10]={0};
printf("%s\n",mystrcpy(str,"asdfgh") );
printf("%s\n",str);
}
3,strlen
#include <stdio.h>
//利用循环来实现
int my_strlen_cycle(char* str)
{
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
//利用递归来实现
int my_strlen_digui(char* str)
{
if (*(str+1))
{
return 1 + my_strlen(str + 1);
}
else
{
return 1;
}
}
//利用指针实现
int my_strlen_ptr(char* str)
{
char* left = str;
char* right = str;
while (*right)
{
right++;
}
return right - left;
}
int main()
{
char input[20]="abcdefghijklmn";
my_strlen_cycle(input);
printf("my_strlen_cycle=%s\n",input);
my_strlen_digui(input);
printf("my_strlen_cycle=%s\n",input);
my_strlen_ptr(input);
printf("my_strlen_ptr=%s\n",input);
return 0;
}
4,strcmp
#include <stdio.h>
int my_strcmp(char* str1, char* str2)
{
while (*str1 == *str2)
{
if (!*str1)
{
return 0;
}
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
int my_strncmp(char* str1, char* str2, size_t n)
{
while (n--)
{
if (*str1 == *str2)
{
str1++;
str2++;
continue;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
return 0;
}
int main()
{
char arr[10]="abcd";
char brr[10]="abcf";
int back=my_strcmp(arr,brr);
printf("back=%d\n",back);
return 0;
}
5,strcat
#include <stdio.h>
char* my_strcat(char* str1, char* str2)
{
char* ret = str1;
while (*str1)
{
str1++;
}
while (*str1++ = *str2++)
{
;
}
return ret;
}
char* my_strncat(char* str1, char* str2, size_t n)
{
char* ret = str1;
while (*str1)
{
str1++;
}
while (n)
{
*str1++ = *str2++;
n--;
}
return ret;
}
int main()
{
char arr[10]="abcdef";
char brr[10]="ghijkmn";
char *p;
p=my_strcat(arr,brr);
while(p!=NULL)
{
printf("%c");
}
printf("\n");
return 0;
}
6,strstr
#include <stdio.h>
#include<stdio.h>
char* my_strstr(char* ptr1, char* ptr2)
{
char* src = ptr1;
while (*src)
{
char* s1 = src;
char* s2 = ptr2;
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
if (!*s2)
{
return src;
}
src++;
}
return NULL;
}
int main()
{
char arr1[] = "abcdef";
char arr2[] = "def";
printf("%s", my_strstr(arr1, arr2));
return 0;
}