打印自定义字符串数据时的奇怪输出(c ++新手)

Posted

技术标签:

【中文标题】打印自定义字符串数据时的奇怪输出(c ++新手)【英文标题】:weird output when printing data of custom string (c++ newbie) 【发布时间】:2012-01-17 05:17:29 【问题描述】:

我主要关心的是我是否安全、高效地执行此操作,并且大部分情况下是否正确。

我需要一些帮助来编写字符串类的实现。也许有人可以帮助我解决我想知道的问题?

我正在尝试编写自己的字符串类来扩展功能和学习目的。我不会用它来代替 std::string 因为这可能是危险的。 :-P

当我使用 std::cout 打印出我的字符串的内容时,我得到了一些意想不到的输出,我想我知道为什么,但我不太确定。我把它缩小到我的分配函数,因为我在字符串中存储字符的任何其他方式都很好。这是我的分配功能:

void String::assign(const String &s)

    unsigned bytes = s.length() + 1;

    // if there is enough unused space for this assignment
    if (res_ >= bytes)
    
        strncpy(data_, s.c_str(), s.length()); // use that space
        res_ -= bytes;
    
    else
    
        // allocate enough space for this assignment
        data_ = new char[bytes];
        strcpy(data_, s.c_str()); // copy over
    

    len_ = s.length(); // optimize the length

我有一个构造函数,它为 char ptr 分配和保存固定数量的字节。它是这样声明的:

explicit String(unsigned /*rbytes*/);

res_ 变量只记录传入的字节数并存储它。这是 string.cpp 中的构造函数代码:

String::String(unsigned rbytes)

    data_ = new char[rbytes];
    len_ = 0;
    res_ = rbytes;

我认为使用这种方法会比为字符串分配新空间更有效。所以当我声明一个新字符串时,我可以使用我最初保留的任何间隔。这是我测试它是否有效的方法:

#include <iostream>

#include "./string.hpp"

int main(int argc, char **argv)

    winks::String s2(winks::String::to_string("hello"));
    winks::String s(10);

    std::cout << s2.c_str() << "\n" << std::endl;

    std::cout << s.unused() << std::endl;
    std::cout << s.c_str() << std::endl;
    std::cout << s.length() << std::endl;

    s.assign(winks::String::to_string("hello")); // Assign s to "hello".

    std::cout << s.unused() << std::endl;
    std::cout << s.c_str() << std::endl;
    std::cout << s.length() << std::endl;

    std::cout.flush();
    std::cin.ignore();

    return 0;

如果您担心 winks::String::to_string,我只是将 char ptr 转换为我的字符串对象,如下所示:

String String::to_string(const char *c_s)

    String temp = c_s;
    return temp;

然而,我在这个方法中使用的构造函数是私有的,所以我强迫自己使用 to_string。到目前为止,我对此没有任何问题。我这样做的原因是为了避免重写不同参数的方法,即:char * 和 String

私有构造函数的代码:

String::String(const char *c_s)

    unsigned t_len = strlen(c_s);
    data_ = new char[t_len + 1];
    len_ = t_len;
    res_ = 0;
    strcpy(data_, c_s);

非常感谢所有帮助。如果我没有提供有效数量的信息,请告诉我您想知道的内容,我很乐意编辑我的帖子。

编辑:我没有发布完整的 string.hpp 和 string.cpp 的原因是因为它相当大,我不确定你们是否愿意。

【问题讨论】:

您在String::assign 中存在内存泄漏。 怎么样?我正在检查是否有足够的预留空间用于分配。我可能做错了。你能详细说明一下吗? else 部分中,您不会在分配之前删除现有的data_。所以你泄露了旧的内容。 assign() 中,您没有复制'\0' 字符。 strncpy(data_, s.c_str(), s.length()); // use that space 这不会保存 '\0' 字符。以下是正确的strncpy(data_, s.c_str(), s.length()+1); // use that space 【参考方案1】:

您必须决定是否始终在内部存储以 0 结尾的字符串。如果您不使用终止零字节存储字符串,则您的 c_str 函数必须添加一个。否则,它不会返回 C 字符串。

您的 assign 函数不会 0 终止。所以要么它坏了,要么你不打算 0 终止。如果是前者,修复它。如果是后者,请检查您的 c_str 函数以确保它在末尾放置一个 0。

【讨论】:

以上是关于打印自定义字符串数据时的奇怪输出(c ++新手)的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Hadoop 中的地图程序中输出具有列表等数据结构的自定义类

在视图模型中更改模型状态(添加自定义验证)

数据未显示在 UITableView 的自定义单元格中

自定义核心数据 SectionNameKeyPath

为自定义对象 oneAPI 创建数据缓冲区时遇到问题

如何使用自定义 XSD 架构编写 XML?