zhanghouxing的个人博客分享 http://blog.sciencenet.cn/u/zhanghouxing

博文

C语言字符处理

已有 4876 次阅读 2016-8-26 21:50 |个人分类:C 语言|系统分类:科研笔记| C语言, 字符串

首先我们来看下面的代码。这个代码,目的是想对一行字符串(以#符号开始)的注释前后空白进行去除。如“  this is what I want   #this is the comment”, 我想得到“this is what i want”。

首先我们将字符串地址赋值给StrStart, 然后判断是否空白,如果是,则将地址向后移动一位,以此类推,这样找到了非空白字符地址(注意:这里没有删掉buffer前面的空白);

然后我们找到#所在的位置,然后将地址赋值给StrEnd (注意:这个地址是指向这个字符及其之后字符所组成的字符串首地址),然后将该地址所指的字符串复制为''字符串结束标识。比如上面的例子,StrEnd会指向“#this is the comment”,赋值过后,*StrEnd = "",即上面的字符变为“   this is what I want   this is the comment ”;因为字符串以''为结束标志,因此当我们对Buffer取值时,会得到“   this is what I want   ”。

最后一步,我们去掉字符串后面的空格。完成!


上面用了两种方法定义字符串,第一种是定义字符指针,然后拷贝字符串;第二种是建立字符数组并初始化。这里注意,不能通过char *Buffer= ""来定义可变字符串。如果定义了,后面就不能对其进行修改了。第一种方法和第二种方法是区别的,第一种,我们修改某个元素为'',后面的元素不改变,但是当我取值时,就只取''前面的内容。第二种,我们修改某个元素为'',后面的元素不改变,因为是数组,我们调试的时候,读取到的值是“xxxx 00xxx”,但对其输出时,因为C语言中字符串是以NUL(00)结尾,所以当读到NUL(00)时就认为字符串已经结束,后面的内容就被忽略了


但是这里好几个与字符串指针,字符数组的相关的问题我之前搞错了。

(1) 首先我之前给字符串Buffer指针赋值,是这样写的,char * Buffer = "# DHSVM INPUT FILE FORMAT", 然后程序执行到23行就报错。原因是这样的。 把"abc"赋给一个字符指针变量时,如
                 char* ptr = "abc";
   因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器最合适的选择。因此当我们试图修改Buffer所指向的内容时,会试图修改常量的值,所以会报错。所以平时写代码是建议这样写:const char * Buffer.

   那为什么char Buffer[]="# DHSVM INPUT FILE FORMAT"这样又不会报错呢。

                char str[] = "abc";
   因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为
   字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析是
   char str[4] = {'a','b','c',''}; 所以当我们修改Buffer的值时,是合法的。


(2) 字符数组赋值问题

 char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的。 但是如写成 char a[10] , a="hello“,这样就会报错了。因为a虽然也是地址(字符数组的首地址),但和普通指针变量有区别,是常量;所以a="hello",我们试图常量a,所以会报错。

(3)memove函数与Memcopy

memcpy() 用来复制内存,其原型为: void * memcpy ( void * dest, const void * src, size_t num );
memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。

需要注意的是:

  • dest 指针要分配足够的空间,也即大于等于 num 字节的空间。如果没有分配空间,会出现断错误。

  • dest 和 src 所指的内存空间不能重叠(如果发生了重叠,使用 memmove() 会更加安全)。


memmove() 用来复制内存内容,其原型为:
   void * memmove(void *dest, const void *src, size_t num);

上面重叠的区域为20-25。

memmove(Buffer, StrStart, strlen(StrStart)+1); Buffer对应"  this is what I want", StrStart对应"this is what I want",内存空间存在重叠。上面的长度加1是因为字符串的结尾标识没计算再长度内。

(4)定义字符串举例

字符串定义其实很简单在c/c++语言中定义一个字符串可以使用如下的语法:

char *s1=“string1”;//定义字符串常量,指针形式

char s2[]=“string2”;//定义字符串变量并初始化,数组形式

char *s3=new char[10];//定义字符串变量并分配内存 指针形式

strcpy(s3,"string3");//为s3赋值

char *s3=new char[10];//定义字符串变量并分配内存 指针形式

strcpy(s3,"string3");//为s3赋值

char s4[10];//定义字符串变量,数组形式

strcpy(s4,"string4");//为s4赋值

以上四种方法都能定义一个字符串,同时通过字符串在内存中的分布可以清楚地知道是什么情况



Ref:

http://www.cnblogs.com/KingOfFreedom/archive/2012/12/07/2807223.html  
http://c.biancheng.net/cpp/html/155.html

http://c.biancheng.net/cpp/html/156.html



https://blog.sciencenet.cn/blog-922140-998942.html

上一篇:截断误差与舍入误差
下一篇:DHSVM 径流 Subdaily to Daily
收藏 IP: 210.72.80.*| 热度|

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-11-25 14:32

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部