Southmountain Ответов: 4

Проблемы длины строки, связанные с strlen()


Я чистю свои навыки C++ и набираю демо-программу, как показано ниже, но у меня есть разная длина исходного текстового значения и целевого текстового значения, так что моя демо-версия выдает исключение. Я пишу эту демонстрацию в Visual Studio 2019. пожалуйста, помогите мне в этом вопросе.

#include <iostream>
#include <string.h>
#include <stdlib.h>     
using namespace std;

class CMessage {
private:
    char* pmessage=0;

public:
    void ShowIt()
    {
        cout << endl << pmessage;
    }

    //constructor
    CMessage(const char* text = "default message")
    {
        pmessage = new char[strlen(text) + 1];
        cout << " the length of text is:" << strlen(text) << endl;
        cout << " the length of pmessage is:" << strlen(pmessage) << endl;

        strcpy_s(pmessage,sizeof pmessage,text);
    }

    //destructor prototype
    ~CMessage();
};

CMessage::~CMessage()
{
    cout << "destructor called."
        << endl;

    delete[] pmessage;
}

int main()
{
    std::cout << "Hello World!\n";
    CMessage Motto("a miss is as good as a smile.");
    Motto.ShowIt();
}


Что я уже пробовал:

Я думаю, что это связано с широкими символьными функциями.

4 Ответов

Рейтинг:
31

Richard MacCutchan

Вам нужно использовать длину исходного сообщения, а не размер указателя:

int msglen = strlen(text) + 1; // the length required to store the message
if (pmessage != nullptr)
    delete[] pmessage; // delete any previous buffer
pmessage = new char[msglen];
cout << " the length of text is:" << strlen(text) << endl;
// the length of pmessage is the same + 1 byte for the null character
strcpy_s(pmessage, msglen, text);


0x01AA

Для меня это имеет смысл, +5

Southmountain

Высоко оценил ваш help.it действительно очистил мои облака...

Richard MacCutchan

Добро пожаловать.

Рейтинг:
2

John R. Shaw

Я мог бы объяснить, почему ваше Кодирование в стиле C не работает, но вместо этого я просто предоставлю более простую версию C++. (это не в моей голове - я не компилировал это, поэтому я ожидаю, по крайней мере, одну ошибку)

#include <iostream>
#include <string>
using namespace std;

class CMessage {
private:
    std::string message;

public:
    void ShowIt()
    {
        cout << endl << message.c_str();
    }

    //constructor
    CMessage(const std::string& text = "default message")
    {
        cout << " the length of text is:" << text.size() << endl;
        cout << " the length of message is:" << message.size() << endl;

        message = text;
    }

    //destructor prototype
    ~CMessage();
};

CMessage::~CMessage()
{
    cout << "destructor called."
        << endl;
}



int main()
{
    std::cout << "Hello World!\n";
    CMessage Motto("a miss is as good as a smile.");
    Motto.ShowIt();
}


Обратите внимание, что если вы используете Ключевое слово " new " в C++, то вы, вероятно, делаете что-то не так. Существуют веские причины для использования указателей и выделения памяти с помощью " new " в C++, но ваша простая программа не является одной из них.

Есть причины, по которым вы можете захотеть передать постоянный указатель c-string методам в C++, но я оставляю это на ваше усмотрение.


Рейтинг:
1

Shao Voon Wong

Просто переоденься с sizeof к strlen(), sizeof вычисляется во время компиляции. sizeof указатель либо дает 4 байта(32-бит) , либо 8 байт(64-бит) и длину вашего источника text длиннее 8 байт. strlen() это делается во время выполнения. И установите 1-й символ из pmessage чтобы нулевой символ означал нулевую длину, потому что pmessage это указывает на новый массив со случайными значениями. Или вы можете memset до нуля-инициализировать весь массив. strlen() проверяет наличие нулевого символа для определения длины строки.

//constructor
CMessage(const char* text = "default message")
{
    if(pmessage) delete [] pmessage; // deallocate pmessage if it is not null, else mem-leak
    pmessage = new char[strlen(text) + 1];
    pmessage[0] = '\0'; // set 1st char to null character to signify 0 length.
    cout << " the length of text is:" << strlen(text) << endl;
    cout << " the length of pmessage is:" << strlen(pmessage) << endl;

    strcpy_s(pmessage,strlen(pmessage)+1,text);
}


Richard MacCutchan

Это неправильно, длина, заданная pmessage, будет равна 1 байту, поэтому strcpy_s потерпит неудачу.

Рейтинг:
0

CPallini

std::string вместе с std::cout обеспечьте (правильно) всю функциональность, которую должен иметь ваш код.
Следовательно, для того, чтобы почистить ваши C++ навыки, дайте взглянуть на их документацию.