当按char插入字符串值到char列表时,为什么要用length+1?

问题描述 投票:0回答:1

当我想把用户的输入作为字符串,然后把每个char值插入到一个新的列表中时,我使用下面的命令。

#include <iostream>
#include <string>
#include <cstring>

using  namespace  std;

int main()
{
    string text;
    cout<<"Text: ";
    cin>>text;

    int len = text.length();
    char char_list[len + 1];

    strcpy(char_list, text.c_str());

    cout << char_list << endl;
    return 0;
}

在上面的代码中,为什么我们使用 char char_list[len + 1];? 如果我不使用 +1我看到同样的结果。

c++
1个回答
2
投票

C 字符串使用字符数组,并附加一个特殊的空字符来表示字符串的结束。这就是所谓的空结束符,它在字符串中的其他字符之后。所以在你的代码中 char_list 是一个C语言的字符串。这是C语言唯一的一种字符串。

C 字符串中的特殊空字符是你需要拥有的原因。len + 1. 该 +1 是为了给空字符留出足够的空间。

在C++中,有一个 std::string 类来表示字符串,所以 text 是一个C++字符串。但C++也可以用C字符串。一般来说,在C++程序中,你应该首选C++字符串。

在C++程序中,一个重要的事实是,你的代码能用,并不意味着它是正确的。所以,即使这次你的工作是为了省去了 +1 下次可能就不行了。这方面的技术术语是 未定义的行为因为你漏掉了 +1 你的程序有未定义的行为。未定义的行为意味着任何事情都可能发生,即使是工作也是未定义的行为,但崩溃或给出错误的结果也是如此。


1
投票

首先,可变长度的数组,如 char_list

int len = text.length();
char char_list[len + 1];

不是一个标准的C++功能。如果使用的C++编译器没有自己的语言扩展,不允许使用可变长度的数组,那么代码将无法编译。

在这种情况下,你应该动态地分配数组

int len = text.length();
char *char_list = new char[len + 1];

另外,使用有签名的类型也是个坏主意。int 来存储一个无符号整数类型的对象。std::string::size_type 类型的对象中,一般情况下,该类型的对象可能太大而无法存储。int

你可以直接使用指定符 auto

auto len = text.length();
char *char_list = new char[len + 1];

尽管如此,使用的C字符串函数 strcpy 将源字符数组中的字符复制到目标字符数组中,直到最后的零字符'/0'不会被复制。也就是末端的零字符 '\0' 扮演了一个哨兵值的角色,它和其他字符一起被存储在一个字符串中。

同样的方式来处理重载操作符 << 当其参数类型为 char *.

如果不为字符数组中的终止符0保留额外的字节,你的程序就会出现未定义的行为,尽管它为这样一个简单的程序提供了预期的结果。

你可以使用另一个字符串函数strncpy或memcpy复制std::string类型的源对象,但不包括结束符零,方法如下。

int len = text.length();
char char_list[len];

memcpy(char_list, text.c_str(), len );

但在这种情况下,你可以不使用操作符<<。相反,你可以写

cout.write( char_list, len ) << endl;
热门问题
推荐问题
最新问题