【问题标题】:string uppercasing adds junk to the end of char array字符串大写将垃圾添加到 char 数组的末尾
【发布时间】:2021-11-13 08:49:00
【问题描述】:

我正在学习 c++,我编写了一些代码来将字符串转换为大写并显示它。我用“asdf”分配一个字符串str,然后创建一个char数组指针并分配一个与字符串相同的长度。

但是当我尝试显示 char 数组时,我用大写字符分配 char 数组的索引后,末尾附加了许多垃圾字符。为什么会发生这种情况,因为我只分配了 size = "length of string" 的 char 数组,那么即使在实际分配的大小之后,char 数组最后如何有垃圾字符。

string str{ "asdf" };
char* str_c = new char[str.length()];   
for (int i = 0; i < str.length(); i++) {
    str_c[i] = toupper(str[i]);     
}
cout << str_c; // displays ASDF²▌r┐│w²A∙

【问题讨论】:

    标签: c++ string


    【解决方案1】:

    您的 char 数组需要比字符串的长度长一个字符,用于空终止符

    string str{ "asdf" };
    char* str_c = new char[str.length() + 1];   
    for (int i = 0; i < str.length(); i++) {
        str_c[i] = toupper(str[i]);     
    }
    str_c[str.length()] = '\0';
    cout << str_c; // displays ASDF
    

    在 C 风格的字符串 (char*) 中,字符串的长度不存储在内存中。因此,它必须使用其他方式来确定字符串的结束位置。这样做的方式是假设字符串是所有字节,直到等于零的字节(所谓的空终止符)。

    如果不为空终止符显式分配一个额外的字节并设置它,您的字符串将继续使用您分配的字节之后的垃圾,直到它遇到(意外)最近的 0。

    【讨论】:

    • 感谢这项工作。但你能解释一下为什么“str_c[str.length()] = 0;”是必需的吗?
    • 在 C 风格的字符串 (char*) 中,字符串的长度不存储在内存中。因此,它必须使用其他方式来确定字符串的结束位置。它这样做的方式是假设字符串是所有字节,直到等于零的字节(所谓的空终止符)。
    • 哦,这很有趣,这是否意味着我的字符串之间不能有 0 作为字符。
    • 如果您的char*s 中需要 0 个字节,大多数库(例如,您从 iostream 使用的 cout,或来自 string.h 的大部分内容)都会中断. string 类(您的代码中的strstring 的一个实例)确实存储了长度,并且在许多情况下正确处理内部的0 个字节。这篇文章比较好embeddedartistry.com/blog/2017/07/26/stdstring-vs-c-strings
    • 有趣的旁注:toupper 的参数是 int,而不是 char,以允许像 EOF 这样的带外代码。当您有签名的chars 时,这可能会导致有趣的问题。标准建议是在调用之前将char 转换为unsigned char,只是为了安全起见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2018-01-27
    • 1970-01-01
    • 2015-05-28
    • 2020-04-19
    • 2016-01-23
    • 2013-08-25
    相关资源
    最近更新 更多