Вопрос

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

#include <iostream>
using namespace std;

class Test {
public:
    void setName(char *name);
    char getName();
private:
    char m_name[30];
};

void Test::setName(char *name) {
    strcpy(m_name, name);
}

char Test::getName() {
    return *m_name;
}

void main() {

    Test foobar;
    char name[] = "Testing";
    foobar.setName(name);
    cout << foobar.getName();
}

Конечно, я ожидаю, что setName () будет хранить строку " Тестирование " внутри класса getName () должна возвращать «Тестирование». Но вместо этого я получаю только первую букву Т. Что я делаю не так?

Полагаю, мне следует использовать строки std, но сначала я бы хотел понять, почему это не работает. Насколько я знаю, это должно работать и с массивами символов?

Это было полезно?

Решение

Просто верните указатель:

const char* Test::getName() const
{
    return m_name;
}

и добавьте конструктор для class Test , который завершит инкапсулированный массив нулем:

Test::Test()
{
    m_name[0] = 0;
}

чтобы не возникало проблем, если кто-то создает экземпляр class Test и не вызывает setName () для экземпляра.

Другие советы

В Test :: getName () вы просто возвращаете один символ (первый символ). Вместо этого вы должны вернуть адрес первого символа, с которого начинается строка, т.е. изменить тип возвращаемого значения на char * , а оператор возврата - return m_name;

Если у вас есть указатель, p , оператор разыменования указателя * " следует " указатель, поэтому выражение * p оценивает любой объект, на который указывает указатель.

Во многих ситуациях имя массива, например m_name , может вести себя как указатель. Таким образом, * m_name соответствует первому char в массиве, поскольку это тип, имя массива которого, когда интерпретируется как указатель, указывает на.

Поскольку строки в C представлены в виде указателей на символы, вы не должны разыменовывать указатель, а возвращать его в целости.

Многие предлагали использовать strncpy () для записи входной строки в ваш массив, так как она выполняет (вроде) проверку границ. Однако, это не оптимально, его семантика нечетна, и копирование строки в ограниченный буфер на самом деле не то, для чего она была разработана. Лучше выяснить, есть ли в вашей среде различные функции snprintf () , и использовать их следующим образом:

snprintf(m_name, sizeof m_name, "%s", name);

И безопаснее использовать strncpy () , чем strcpy () в void Test :: setName ()

Если вы хотите, чтобы это был C ++, просто не используйте указатели на символы, если у вас нет для этого особой причины!

Переключитесь с указателя на символ в std :: string и посмотрите, решит ли это вашу проблему:

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

class Test {
public:
    void setName(std::string name);
    std::string getName();
private:
    std::string m_name;
};

void Test::setName(std::string name) {
    m_name = name;
}

std::string Test::getName() {
    return m_name;
}

void main() { 
    Test foobar;
    foobar.setName("Testing");
    cout << foobar.getName();
}

Для бонусных баллов сделайте тип параметра в setName const std :: string & amp;.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top