一、基本概念
- 以0(整數0)結尾的一串字符;
- 0或者’\0’是一樣的,但和’0‘不同;
- 0標誌着字符串的結束,但它不是字符串的一部分;
- 計算字符串長度時不包含這個零;
- 字符串以數組的形式存在以數組或指針的形式訪問;
- 頭文件#include<string.h>包含很多處理字符串的函數;
二、字符串常量和字符串變量
C語言中沒有直接存儲字符串的變量,一般通過數組存儲:
因此字符串變量實質上是:字符數組;
初始化如下:
char *str = "Hello";
char word[] = "Hello";
char line[10] = "Hello";
/* 選擇指針還是數字組?
數組:可以找到字符串的地址(word[0]);
作爲本地變量自動被回收;
指針:不能確定其地址;
多用於處理函數,動態分配空間*/
"Hello"就是字符串常量(字符串字面量),
它會被編譯器變成一個字符數組放在某處,這個數組的長度是6,因爲結尾還有一個結束符’\0’;
注:兩個相鄰的字符串常量會被自動連接起來;
綜上,C語言的字符串:
- 以字符數組的形式存在;
- 不能用運算符對字符串運算;(因爲數組是const)
- 通過數組的方式可以遍歷字符串。
三、字符數組和字符串數組辨析
/* 字符串數組 */
#include<stdio.h>
int main(void)
{
int i,j;
//a[3][10]爲二維數組,也可以看成是內含3個數組的數組
//a[3][10]佔用30個字節,初始化時如果某個字符串超過10,就會溢出內存
//它的字符串字面量可以更改
char a[3][10] = {"abc",
"abcd",
"abcde"};
//*str[3]可以看成是內含3個指針的數組,不會浪費內存空間
//它的字符轉字面量不能修改
const char *str[3] = {"123",
"1234",
"12345"};
for( i= 0; i<3; i++){
printf("%s\n",a[i] );
};
for( j= 0; j<3; j++){
printf("%s\n",str[j]);
};
return 0;
}
四、字符串函數
1、strlen
返回字符串s的長度
/* 字符串函數學習1,getchar(),putchar(),strlen()的使用 */
/*strlen
size_t strlen(const char *s)
返回s的字符串長度(不包括'\0')*/
#include<stdio.h>
#include<string.h>
int mylen(const char *s);//自己寫一個函數實現strlen()功能
int main(int argc,char const *argv[]) //這裏argc變量表示輸入字符串個數,*argv[]表示輸入字符串,該函數功能爲原樣照輸你輸入的字符和數
{
char line[] = "Hello";
printf("Strlen = %lu\n",strlen(line));
printf("Strlen = %lu\n",mylen(line));
printf("Sizeof = %lu\n",sizeof(line));
char a;
a = getchar();
putchar(a);
return 0;
}
int mylen(const char *s) //編寫一個mylen()函數實現strlen()的功能
{
int cnt = 0;
while(s[cnt] != 0){
cnt++;
}
return cnt;
}
2、strcmp
比較字符串s1,s2是否相同,相同返回0;
s1 >s2,返回1;
s1<s2,返回-1;
/* 字符串函數練習2,strcmp()和相同功能的mycmp() */
/*int strcmp(const char *s1,const char *s2);*/
//函數strcmp()是比較兩個字符串是否相同,相同就返回0,否則是1(前面大於後面)、-1
#include<stdio.h>
#include<string.h>
int mycmp1(const char *s1, const char *s2);
int mycmp2(const char *s1, const char *s2);
int main(int argc, char const *argv[])
{
char s1[] = "abc";
char s2[] = "abc";
char s3[] = "abc ";
printf("%d\n",strcmp(s1,s2));
printf("%d\n",strcmp(s1,s3));
printf("%d\n",mycmp1(s1,s2));
printf("%d\n",mycmp1(s1,s3));
printf("%d\n",mycmp2(s1,s2));
printf("%d\n",mycmp2(s1,s3));
return 0;
}
int mycmp1(const char *s1,const char *s2) //用指針數組每個單元的比較,當滿足相等並且爲字符終止標誌'\0'時,返回它們的差
{
int idx = 0; //定義一個下標計數器
while( s1[idx] == s2[idx] && s1[idx] !='\0'){
idx++;
}
return (s1[idx] - s2[idx]);
}
int mycmp2(const char *s1,const char *s2) //這個直接用指針操作字符串,省區了創建s1[idx]的內存空間,更巧妙
{
while( *s1 == *s2 && *s1 != '\0'){
s1++;
s2++;
}
return (*s1 - *s2);
}
3、strcpy
複製字符串src到新的字符串空間dst並返回dat
/* 字符串函數練習3,包括strcpy()和strcat() */
/* char *strcpy(char *restrict dst,const char * restrict src);
返回dst */
#include<stdio.h>
#include<string.h>
char *mycpy(char *dst, const char *src );
int main(int argc,char const *argv[])
{
char s1[] = "abc";
char s2[] = "bcd";
char s3[] = "cde";
printf("%s\n",s1);
printf("%s\n",s2);
strcpy(s1,s2);
printf("%s\n",s1);
mycpy(s1,s3);
printf("%s\n",s1);
return 0;
}
char *mycpy(char *dst, const char *src) //指針版版mycpy
{char *ret = dst;
while(*src != '\0'){
*dst++ = *src++;
}
*dst = '\0';
return ret;
}
/*數組版mycpy
char *mycpy*(char *dst, const char *src)
{int idx;
while(src[idx] != '\0'){
dst[idx] = src[idx];
idx++;
}dst[idx] ='\0';
return dst;
}
*/
4、strcat
strcat
char *strcat(char *restrict s1, const char *restrict s2);
/* 把s2拷貝到s1的後面,接成一個長字符串
返回s1; */
5、字符串中找字符
char *strchr(const char *s,int c);//從左找單個字符
char *strrchr(const char *s,int c);//從右邊找單個字符