странный вывод при печати данных пользовательской строки (c ++ новичок) - PullRequest
0 голосов
/ 17 января 2012

Моя главная проблема в том, что я делаю это безопасно, эффективно и, по большей части, правильно.

Мне нужна помощь в написании моей реализации строкового класса. Может быть, кто-то может помочь мне с тем, что я хотел бы знать?

Я пытаюсь написать свой собственный строковый класс для расширенной функциональности и в целях обучения. я не буду использовать это вместо std :: string, потому что это может быть потенциально опасно. : -Р

когда я использую 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, я просто конвертирую 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);
}

вся помощь очень ценится. если я не предоставил эффективное количество информации, пожалуйста, сообщите мне то, что вы хотите знать, и я с удовольствием отредактирую свой пост.

edit: причина, по которой я не публикую полный string.hpp и string.cpp, заключается в том, что он довольно большой, и я не уверен, что вам, ребята, понравится.

1 Ответ

2 голосов
/ 17 января 2012

Вы должны принять решение, будете ли вы всегда хранить свои строки с внутренним завершением на 0. Если вы не сохраняете свои строки с завершающим нулевым байтом, ваша функция c_str должна добавить один.В противном случае он не возвращает C-строку.

Ваша assign функция не завершается 0.Так что либо он сломан, либо вы не намеревались завершить 0.Если первое, то исправь.Если последнее, проверьте вашу c_str функцию, чтобы убедиться, что она ставит 0 в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...