在C/C++中,字符串以'\0'结尾是一种强制要求,或者说,只有满足这个要求的

字符数组才能被称为字符串。否则,你所做的所有操作结果都是未定义的

C标准库string.h中所有关于字符串的函数都有一个特性,对于输入字符串,默认为是以'\0'结尾的

,否则就会出现未定义行为,比如strlen,实现就依赖了这一点:

int len = 0;

while(*s++)len++;对于输出字符串(一把是返回一个char*指针),也保证在末尾加上一个'\0'

本来,如果把字符串完全当成整体(像std::string那样)的话,是不用担心这个问题的,但是C/C++里面

字符串又是以字符数组的形式存在的,所以会出现这样的代码

char a[] = {'a', 'b', 'c', 'd'};

size_t len = strlen(a);

能通过编译,因为类型检查不会出错,但是运行时行为却很诡异,基本是错的,正确的定义方式

应该是这样的char a[] = {'a', 'b', 'c', 'd', '\0'};

这个坑也影响到了stl里面string的实现,比如string的data()方法和c_str()方法默认返回的char* 就一定是以'\0'结尾的

但可怕之处就在于string又可以拆开来用,看下面代码:

#include<iostream>
#include<string.h>
#include<string>
using namespace std;
int main() {
char a[] = { 'a', 'b', 'c', 'd','\0'};
string s(a);
cout << s.size() << endl;
cout << s.length() << endl;
s[4] = 'e';
cout << s << endl;
cout << s.size() << endl;
cout << s.c_str() << endl;
cout << s.data() << endl;
return 0;
}

有没发现开始的size和length的输出都符合C里面关于一个字符串的定义(排除那个'\0')

但是对于s[4] = 'e'这种会破坏字符串结构的行为,编译器竟无动于衷,导致后面s.c_str()输出就是乱码。

www.cplusplus.com里面关于string类的operator[](int)方法和at(int)方法的说明如下:

   char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
If pos is equal to the string length, the function returns a reference to the null character that follows the last character in the string (which should not be modified).
索引允许等于length,但是should not be modified! 也就是如果修改就是未定义行为
      char& at (size_t pos);
const char& at (size_t pos) const;
Get character in string
Returns a reference to the character at position pos in the string.

The function automatically checks whether pos is the valid position of a character in the string (i.e., whether pos is less than the string length), throwing an out_of_range exception if it is not.

这个函数倒是严格规定不许索引到length处!否则会有异常!

总结:字符串和字符数组不是一回事!而标准库里string类仍旧是以普通字符数组的形式来实现字符串的,

所以也留下了可能破坏字符串结构的隐患!

C语言string.h中所有不带n的字符串函数其实都假设了输入是合法的null terminated string,否则会造成未定义行为

比如 strcpy 应该改用 strncpy

      strcmp 应该改用strncmp

      strcat 应该改用strncat

      这里面的n全部都是包括'\0'在内的总字节数,简单解释就是,一般我们的字符串操作函数都是循环直到'\0'为止,现在

多了一个结束出口,就是到达n处为止!

另外像strlen 甚至C++里面char_traits::length对于不以'\0'结尾的字符串也是有隐患的,输入未定义行为!

C/C++ 字符串 null terminal的更多相关文章

  1. Java字符串null相加

    Java字符串null相加 最近和同事讨论了下面的一段代码: String a = null; a += a; System.out.println(a); 运行结果: nullnull 本着学习的态 ...

  2. Net Core 下 Newtonsoft.Json 转换字符串 null 替换成string.Empty

    原文:Net Core 下 Newtonsoft.Json 转换字符串 null 替换成string.Empty public class NullToEmptyStringResolver : De ...

  3. 空字符串‘’ null false 区别

    1.''空字符串 .null 和false都是以值为0来存储的   只是数据结构不一致而已 空字符串------字符串数据格式 null -----------null数据格式 false ----- ...

  4. Asp.Net Core 下 Newtonsoft.Json 转换字符串 null 替换成string.Empty

    public class NullToEmptyStringResolver : DefaultContractResolver { /// <summary> /// 创建属性 /// ...

  5. spring boot 返回json字符串 null值转空字符串

    @Configuration public class JacksonConfig { @Bean @Primary @ConditionalOnMissingBean(ObjectMapper.cl ...

  6. PHP递归方式把一个数组里面的null转换为空字符串”的方法

    在一些接口的调用中,直接查询数据库出来的字段可能为null字段,但是为了简便前端的判断,需要把null转换成空字符串'',这个时候就需要递归的方式进行.直接上代码如下: //递归方式把数组或字符串 n ...

  7. laravel之null替换空字符串中间件

    在laravel写接口的时候免不了数据库中保存null,可用诸如设置ORM的访问器或以下方法处理 $goods->name?$goods->name:''; 其实可以利用路由中间件,在需要 ...

  8. PHP 中空字符串介绍0、null、empty和false之间的关系

    0是数字,是empty,是false,不是null,值相当于空字符串,但类型不是字符串,去空格或强制转换为字符串型时不等于空字符串 ""的值相当于0,是empty,是空字符串,是f ...

  9. 空字符串(“”)和null和空格字符串(" ")的区别

    1.类型 null表示的是一个对象的值,而并不是一个字符串.例如声明一个对象的引用,String a = null ;""表示的是一个空字符串,也就是说它的长度为0,但它是一个字符 ...

随机推荐

  1. Windows下Git的安装及配置

    Git的BASH Git的为Windows提供了用于命令行运行的一个仿真BASH的Git.习惯LINUX和UNIX环境的你,可以在该BASH环境中输入“git”命令来完成各种版本控制的操作. 简介 G ...

  2. servlet和web容器之间的关系

    Java是一种动态加载和运行的语言.也就是说当应用程序持有一个类的地址(CLASSPATH)和名称(包名和类名)的情况下,可以在程序运行期 间任何时候加载这个类,并创建和使用该类的对象.Servlet ...

  3. hdu--(1025)Constructing Roads In JGShining's Kingdom(dp/LIS+二分)

    Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65 ...

  4. javaSE之如何将一个文档显示出来(,txt,.doc,.....)

    package DEMO ; import java.io.File; import java.io.FileInputStream; import java.io.IOException; impo ...

  5. 接入WebSocket

    闲扯 WebSocket 以前没用过,之前写过一篇博客是基于原生socket的(查看)比较复杂,慎入.今天另外一个APP需要接websocket了,然后便找到了facebook的 SocketRock ...

  6. placehold.it-在线图片生成器(转载)

    做网站的时候 如果 有的产品等客户没有上传图片,可以用这个网站生成的图片 并配以文字进行图片的占位 以免造成页面的空挡或者页面错位等 原文地址:http://www.cnblogs.com/xumen ...

  7. SAP 质检使用非物料基本单位

    今天也是奇葩了,物料A基本单位平方米,转化单位卷,销售和采购是按照平方米来采购,但是质检的需要按照平方米来做抽样检验.... 程序开发的: 修改该物料的工序基本单位为卷,再修改检验计划基本单位为卷 程 ...

  8. Objective-C:Foundation框架-概述

    iOS的整体架构(以iOS8为例)图如下: 从Cocoa Touch到Core OS下面四层包含了开发iOS应用程序所用到的所有API(第三方框架也是基于这几个层的).每个层又都包含了许多框架.框架就 ...

  9. 关于for循环条件性能问题

    昨天看一博客写到一条 尽量使用 for(int i=0,ct=list.Count();i<ct;i++){} 这样的格式,因为我平时一般都是用for(int i=0;i<list.Cou ...

  10. PHP 获取网上文件内容

    <?php $ch = curl_init("http://game.qq.com/comm-htdocs/js/game_area/moba_server_select.js&quo ...