1. 程式人生 > 實用技巧 >7.字串與字元陣列

7.字串與字元陣列

字串與字元陣列

1.1字元陣列定義

char array[100];

1.2字元陣列初始化

char array[100]={'a','b','c','d'};
char array[100]="abcd";
char array[100]={0};
char array[]="abcd";

1.3隨機數產生函式rand與srand

  • 標頭檔案stdlib.h

  • rand是偽隨機數產生器,每次呼叫rand產生的隨機數都是一樣的

  • 如果呼叫rand之前先呼叫srand就出現任意的隨機數

  • 只要能保證每次呼叫srand函式的時候,引數的值是不同的,那麼rand函式就一定會產生不同的隨機數

#include <stdio.h>
#include <time.h>
#include <stdlib.h>//呼叫隨機數的標頭檔案
//* rand是偽隨機數產生器,每次呼叫rand產生的隨機數都是一樣的
//* 如果呼叫rand之前先呼叫srand就出現任意的隨機數
//* 只要能保證每次呼叫srand函式的時候, 引數的值是不同的, 那麼rand函式就一定會產生不同的隨機數
int main() {
	int t = (int)time(NULL);
	srand(t);//可以嘗試將這個註釋,這個是呼叫time這個函式的。
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n", rand());
	}
return 0;
}

1.4用scanf輸入字串

字串的結束標誌
scanf將回車, 空格都認為是字串輸入結束標誌.

#include <stdio.h>

int main() {
	char s[10] = { 0 };
	scanf("%s", s);//"%s"的作用就是輸入一個字串的,scanf是以回車鍵作為輸入完成標示的,但回車鍵本身並不會作為字串的一部分
//如果scanf引數中的陣列長度小於使用者在鍵盤輸入的長度,那麼scanf就會緩衝區溢位,導致程式崩潰
	int i;
	for (i = 0; i < 10; i++) {
		printf("%d\n", s[i]);
}
	printf("----------------------------------\n");
	printf("%s\n", s);
	return 0;
}

2、字串處理函式

2.1、gets

#include <stdio.h>
int main() {
	char s[100] = { 0 };
	gets(s);//gets認為回車的輸入結束標示,空格不是輸入結束標示,所以用gets這個函式就可以實現輸入帶空格的字串
	//gets和scanf一樣存在緩衝區溢位的問題
int i;
for (i = 0; i < 10; i++) {
	printf("%d\n", s[i]);
}
printf("----------------\n");
printf("%s\n", s);
    }
//gets不能用類似'%s'或者'%d'之類的字元轉義,只能接受字串的輸入*/

/*//

2.2、fgets函式

講解視訊01:11:34

gets函式不檢查預留緩衝區是否能夠容納使用者實際輸入的資料。多出來的字元會導致記憶體溢位,fgets函式改進了這個問題。
由於fgets函式是為讀取檔案設計的,所以讀取鍵盤時沒有gets那麼方便

char s[100] = { 0 };
fgets(s, sizeof(s), stdin);

stdin 是標準輸入,一般指鍵盤輸入到緩衝區裡的東西。

2.2.1、gets 與 fgets 的區別:

比如我定義了一個
char x[5];
gets(x);//如果我輸入超過五個字元,如,abcdefg。那麼程式會報錯的
而fgets則不會
fgets(x, sizeof(s), stdin);//如我輸入:abcdefg,它就只會顯示abcd。

2.3、puts

//puts函式列印字串,與printf不同,puts會在最後自動新增一個'\n'
//也就是說,與printf類似,但是它會自動換行

#include <stdio.h>

int main() {
	char s[] = "hello world";
	puts(s);
return 0; 
}

2.4、strlen,字串長度

#include <stdio.h>
int main() {
	//strlen, 字串長度
//size_t strlen(const char* _Str); 返回不包含字串結尾'\0'的字串長度
	char s[100] = "hello world!";
	int len = strlen(s);//得到字串長度,返回一個字串中有效字元的數量(不包含字串結尾的0)
	printf("%d\n", len);
	return 0;
}
/*#include <stdio.h>
int _Str1(const char* _Str) {
	int len = 0;
	if (_Str != NULL) {
		while ((*_Str++) != '\0')
			len++;
	}
	return len;
}

int main() {
	char s[100] = "hello world!";
	int len = _Str1(s);
	printf("%d\n", len);
	return 0;
}*///_Str1與前面的strlen用法是一樣的,不一樣的是,這個是自己定義的函式

/*

2.5、strcat,字串追加

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//strcat, 字串追加

int main(){
	//size_t strcat(char* _str1,const char* _str2) 將引數_str2追加到_str1後尾
	char s[128] = "Hello World!";
	int len = strlen(s);//計算s字串長度,返回一個字串中的有效字元數量(不包含字串結尾的0)
	printf("len=%d\n", len);
	char s1[100] = "abc123321";
	strcat(s, s1);//將兩個字串合併,結果放入第一個引數裡面,strcat也存在緩衝區溢位的問題
	printf("%s\n", s);
	return 0;

}
//自定義strcat函式實現
void _strcat(char* _str1, const char* _str2) {
	if (_str1 != NULL && _str2 != NULL) {
		while (*_str1 != '\0')
			_str1++; //迴圈至str1字串末尾
		while (*_str2 != '\0')
			*_str1++ = *_str2++; //把字串_str2裡面的內容儲存至_str1中
		*_str1 = '\0';//結尾str1賦值'\0'表示字串結束
	}
}

或者

#include <stdio.h>
#include <string.h>
int main(){
	char a[100] = "hello world";
	char b[100] = "123456abc";
	int len = strlen(a);		//計算有效字串長度
	for (size_t i = 0; i < strlen(b); i++)//將超出的長度的無效字串,拼接上字元陣列b裡面有效的字串。
	{
		a[len + i] = b[i];
	}
	printf("%s\n", a);
}

2.6、strncat, 字串有限追加

size_t strncat(char* _str1,const char* _str2,size_t len)
char s[128] = "hello";
char s1[50] = ",world!!!";

strncat(s, s1, 5);
printf("%s\n", s);
//自定義strncat函式實現
void _strncat(char* _str1, const char* _str2, size_t len){
	if (_str1 != NULL&&_str2 != NULL){
		while (*_str1 != '\0')_str1++;
		for (int i = 0; i < len; i++){
			*_str1++ = *_str2++;
		}
	}
}

2.7、strcmp, 字串比較

//int strcmp(const char* _str1,const char* _str2);
#include <stdio.h>
#include <string.h>
int main() {
//比較兩個字串是否相等,相等返回0,不等返回非0
char a[128] = "abcdefg";
char b[128] = "abcdef";
printf("%d\n", strcmp(a, b));//>大於:-1  等於:0 小於:1
return 0;
}
//自定義strcmp函式實現
int _strcmp(const char* str1,const char* str2){
int ret = 0;
if (str1 != NULL&&str2 != NULL){
	while (!(ret = *str1 - *str2) && *str1){
		str1++;
		str2++;
	}
}
if (ret > 0)
	return 1;
else if (ret < 0)
	return -1;
return 0;
}

2.8、strncmp, 字串有限比較

	//	int strcmp(const char* _str1, const char* _str2, size_t len);
	char a[128] = "abcdefg";
	char b[128] = "abcdef";
	int len = 7;
	printf("%d\n", strncmp(a, b, len));//>大於:-1  等於:0 小於:1

2.9、strcpy字串拷貝

//int strcpy(const char* _str1, const char* _str2, size_t len);

char a[128] = "abcdefg";
char b[128] = "hijklnm";
printf("%s\n", strcpy(a, b));//會將b的資料複製到a的資料
printf("%s\n", a);
//自定義strcpy函式實現
void _strcpy(char* _str1,const char* _str2){
	if(_str1!=NULL&&_str2!=NULL){
 		while((*_str1++=*_str2++)!='\0')
	}    
}

2.10、strncpy字串有限拷貝

2.11、sprintf,格式化字串

和printf函式功能類似,printf函式將格式化結果輸出到螢幕,sprintf將格式化結果輸出到字串

char str[128];
sprintf(str, "Hello World!\n");//將結果存在str裡面。
printf("%s\n", str);
//編號加內容。
//平常:
for (size_t i = 0; i < 100; i++)
{
	printf("%d:%s\n", i,"Hello World!");//無可修改的字元變數
}
//用sprintf:
for (size_t i = 0; i < 100; i++)
{
	sprintf(str, "%d:Hello World!\n",i);//str可修改
	printf("%s\n", str);
}

2.12、sscanf函式

sscanf類似於scanf函式, ,scanf從鍵盤讀取使用者輸入,sscanf從指定格式化字串讀取輸入

//爬蟲  模擬使用者去批量下載網站、資訊、內容、圖片、素材
char str[] = "http://www.netbian.com/desk/22925.htm";
char s[128];
sscanf(str, "%[a-z]", s);//"%[a-z]"是指篩選a到z的字母字元
printf("%s\n", s);
char s[128] = "10 0x10 aabc";
int x, y;
char b[100];
sscanf(s, "%d %X %[a-z]", &x, &y, b);//將整型存在x中,將16進位制的存在y中,將字母只有a到z的字元存在b中。
printf("%d\n", x);//
printf("%x\n", y);
printf("%s\n", b);

2.13、strchr查詢字元

//char * strchr(char * _Str, int _Ch);
//在引數_str中查詢引數_Ch指定字元,找到返回字元_Ch在_Str中所在位置,沒有找到返回NULL;
char Str[128] = "Hello World!";
int a = strchr(Str, 'o');

printf("%s\n", (strchr(Str, 'W') + 3));
printf("%c\n", *(char*)(strchr(Str, 'W') + 3));//*(char*)是讓它只輸出一個字母
//自定義strchr函式實現
char *strchr(const char* _str1, int ch) {
	if (str1 != NULL) {
		while (*_str1++ != '\0') {
			if (*_str1 == ch) {
				return (char*)_str1;
			}
		}
	}
	return NULL;
}

2.14、strstr,查詢

strstr:char* strstr(char* _str,const char* _substr)
//在引數_str中查詢引數_substr指定子串,找到返回子串在_str中所在位置,沒有找到返回NULL
char Str[128] = "ldkfjeljaljfe";
char a[10] = "fj";
printf("%s\n",strstr(Str, a));
//爬蟲可以用:
char str[] = "http://www.xinhuanet.com/politics/leaders/xijinping/jhqw.htm";
char http[128] = "www";
printf("%s\n", strstr(str, http));
//自定義strstr函式實現
char* _strstr(char* _str, const char* _substr) {
	if (_str != NULL && _substr != NULL) {
		int lenstr = strlen(_str);
		int lensub = strlen(_substr);
		if (lenstr < lensub)
			return NULL;
		int i, j;
		for (i = 0; i < lenstr - lensub; i++) {
			for (j = 0; j < lensub; j++) {
				if (_str[i + j] != _substr[j])
					break;
			}
			if (j == lensub)
				return &_str[i];
		}
	}
	return NULL;
}

2.15、strtok分割字串

字元在第一次呼叫時strtok()必需給予引數s字串,往後的呼叫則將引數s設定成NULL每次呼叫成功則返回指向被分割出片段的指標

char str[] = "abc@defg@igk";
	char* p = strtok(str, "@");
	printf("%s\n", p);//就會擷取到abc
//與前面的strstr合用。我們只要www,baidu.com
char strh[] = "http://www.xinhuanet.com/politics/leaders/xijinping/jhqw.htm";

char str1[128];
sprintf(str1,strstr(strh, "www"));
char str2[128];
sprintf(str2,strtok(str1, "/"));
printf("%s\n", str2);
//或者
char www[30] = "www";
char* po = strstr(strh, www);
po = strtok(po, "/");
printf("%s\n", po);

atoi轉化為int atof轉化為float atol轉化為long
需要包含標頭檔案stdlib.h