7.字串與字元陣列
阿新 • • 發佈:2020-10-26
字串與字元陣列
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