• 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对于不以''结尾的字符串也是有隐患的,输入未定义行为!

  • 相关阅读:
    JSON.stringify() & JSON.parse() 实现
    节流(Throttling) & 防抖(Debouncing)
    instanceof实现
    new实现
    如何实现深拷贝
    #FFF转换为rgba(255,255,255,1)
    hdcms v5.7.0学习笔记
    Laravel5.x 封装的上传图片类
    JQ 封装全选函数
    双击 ajax修改单元格里的值
  • 原文地址:https://www.cnblogs.com/hustxujinkang/p/4799162.html
Copyright © 2020-2023  润新知