求字符串的长度问题

  在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'后读取到这里的时候,就会停止读取了,而不会再继续读取。
posted @ 2017-10-26 22:54  SmartGame  阅读(2610)  评论(0编辑  收藏  举报