zoukankan      html  css  js  c++  java
  • C/C++ 字符串 null terminal

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

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

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

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

     int len = 0;

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

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

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

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

    size_t len = strlen(a);

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

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

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

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

    #include<iostream>
    #include<string.h>
    #include<string>
    using namespace std;
    int main() {
    	char a[] = { 'a', 'b', 'c', 'd',''};
    	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里面关于一个字符串的定义(排除那个'')

    但是对于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全部都是包括''在内的总字节数,简单解释就是,一般我们的字符串操作函数都是循环直到''为止,现在

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

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

  • 相关阅读:
    织梦CMS去广告方法 for DedeCMS V5.7
    织梦网站底部的Power by DedeCms怎么去掉?
    java环境变量最佳配置
    HTML课上小结
    PHP四个阶段目标以及第一阶段学习内容
    例子:选项卡和进度条
    例子:轮播效果
    例子:下拉列表
    document对象操作:浏览器页面文件
    Windows对象操作:浏览器窗口信息
  • 原文地址:https://www.cnblogs.com/hustxujinkang/p/4799162.html
Copyright © 2011-2022 走看看