求字符串的長度問題
阿新 • • 發佈:2017-10-27
分享 讀取 就會 報錯 字符 clas 符號 定義 fin
在C語法中我們可以定義一個數組當作字符串,或者直接將指針指指向一個字符串,所以我們有時候得拿出字符串中對我們有用的東西:比如
1.現在有一個字符串" abcd ",要求出字符串去掉空格的長度 2.打印出去掉空格之後的字符串
按照題意我們需要求出長度,並去掉空格,下面我會寫出兩個不同的代碼,看看有什麽區別;
首先是第一種
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5#include <ctype.h> 6 7 void trimblank(char *str,int *len); 8 9 10 void main() 11 { 12 char *str = " abcd "; 13 int len = 0; 14 trimblank(str,&len); 15 printf("%d\n",len); 16 printf("%s\n",str); 17 system("pause"); 18 return; 19 } 20 void trimblank(char *str,int*len) 21 { 22 int begin = 0;//開頭的下標 23 int end = strlen(str) - 1;//結尾的下標 24 int LenCount = 0; 25 if(str == NULL || len == NULL)//判斷傳過來的地址是否為空 26 { 27 return ; 28 } 29 if(isspace(str[begin]) && str[begin] != ‘\0‘)//isspace()判斷是否為空字符 30 { 31 begin++; 32 }33 34 if(isspace(str[end]) && str[end] != ‘\0‘) 35 { 36 end--; 37 } 38 39 LenCount = end - begin + 1; 40 *len = LenCount; 41 strncpy(str,str+begin,LenCount);//copy函數 42 str[LenCount] = ‘\0‘;//將結尾制成‘\0‘ 43 44 return ; 45 46 47 }
上面這段代碼我們可以發現,長度可以被求出來,但是copy函數時會報錯,編譯器會說指針指向的空間無法被修改,那麽為什麽無法修改,char *str = " abcd ";通過這句代碼我們可以知道指針指向的是全局區,即下圖所示:
然後我們可以看出來我們分配的是全局區的字符串常量,記住是常量,所以內存空間無法被修改,當我們試圖往當中copy數據時
編譯器會報錯。所以說為了讓其能夠被修改,我們一般都會使用可修改的內存空間,比如在這裏,我們可以使用臨時區(棧區)分配的空間來儲存數據;
代碼如下:
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <ctype.h> 6 7 void trimblank(char *str,int *len); 8 9 void main() 10 { 11 //char *str = " abcd "; 12 char str[10] = " abcd ";//將字符串導入到臨時區 13 int len = 0;// 14 15 trimblank(str,&len); 16 printf("%d\n",len); 17 printf("%s\n",str); 18 system("pause"); 19 return; 20 } 21 22 void trimblank(char *str,int *len) 23 { 24 int begin = 0;//開頭的下標 25 int end = strlen(str) - 1;//結尾的下標 26 int LenCount = 0; 27 if(str == NULL || len == NULL)//判斷傳過來的地址是否為空 28 { 29 return ; 30 } 31 if(isspace(str[begin]) && str[begin] != ‘\0‘)//isspace()判斷是否為空字符 32 { 33 begin++; 34 } 35 36 if(isspace(str[end]) && str[end] != ‘\0‘) 37 { 38 end--; 39 } 40 41 LenCount = end - begin + 1; 42 *len = LenCount; 43 strncpy(str,str+begin,LenCount); 44 str[LenCount] = ‘\0‘; 45 46 return ; 47 48 }
當我們使用臨時區儲存數據時,會把全局區的數據copy一份到臨時區,而函數中的指針則指向了臨時區的地址,而臨時區的空間是可以改變的;
關於函數中的代碼,strlen是計算字符串中的到非空字符位置的個數,這個非空並非指空格,空格也是字符,這個空是指‘\0‘,字符串的終止符,即讀取字符串時,一旦遇到這個符號,就會停止讀取。也就是說這個位置什麽數據都沒有。
str[LenCount] = ‘\0‘;這一句估計有人看的不是很懂,我來解釋一下,因為數組的下標都是從零開始的,LenCount是字符串的長度4,也就是說d這個字符會被寫到下標為3的位置,
我們知道‘\0‘是字符串的終止符所以在d後面加一個‘\0‘後讀取到這裏的時候,就會停止讀取了,而不會再繼續讀取。
求字符串的長度問題