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

时间:2012-01-17 05:17:29

标签: c++ string c++11

我主要担心的是,如果我安全,有效地执行此操作,并且大部分时间都是正确的。

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

我正在尝试编写自己的字符串类,以实现扩展功能和学习目的。我不会用它作为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的原因是因为它相当大,我不确定你们是否愿意。

1 个答案:

答案 0 :(得分:2)

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

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