У меня возникли проблемы с использованием strcpy
с vector
экземпляров моего собственного класса. Вот класс:
class elemente {
char name[5];
short val;
bool red;
};
Итак, я сделал вектор из этого класса:
vector<elemente> ele(1);
Но если я попытаюсь сделать эту операцию:
strcpy(ele.back().name, strtok(line, " "));
Я всегда получаю ошибку сегментации. Зачем?
Я использовал GDB для отладки моей программы, и line
переменная верна, а также если я заменю вектор нормальным char *
все работает нормально (программы не работают, но с содержимым все в порядке).
Что я могу сделать?
Поскольку вы используете C ++, вы должны использовать возможности, которые предоставляет этот язык, вместо того, чтобы бороться с кодом в стиле C. Это хорошо, что вы решили использовать std::vector
так что продолжайте и используйте std::string
для хранения строк, std::istringstream
для создания входного потока, который вы будете читать токены и std::getline
на самом деле получить эти токены.
Сначала используйте спецификатор доступа public
сделать атрибуты elemente
класс доступен за пределами этого класса и изменить тип name
в std::string
:
class elemente
{
public:
std::string name;
// ...
};
Тогда получение токенов из строки может выглядеть так:
#include <iostream>
#include <vector>
#include <sstream>
...
std::vector<elemente> elements;
std::string line("this is my input line");
std::istringstream lineStream(line);
for (std::string word; std::getline(lineStream, word, ' '); )
{
if (!word.empty())
{
elements.push_back(elemente());
elements.back().name = word;
}
}
И чтобы проверить этот код, вы можете просто напечатать все имена, хранящиеся в элементах этого вектора:
std::vector<elemente>::iterator e;
for(e = elements.begin(); e != elements.end(); ++e)
std::cout << e->name << ".";
выходы:
this.is.my.input.line.
В качестве альтернативы вы можете создать открытый конструктор вашего класса, чтобы вы могли создавать свои элементы с правильно инициализированными членами:
class elemente
{
public:
elemente(const std::string& s) : name(s){ }
// ...
std::string name;
// ...
};
Тогда разбор токенов стал бы:
for (std::string word; std::getline(lineStream, word, ' '); )
{
if (!word.empty())
elements.push_back(elemente(word));
}
Надеюсь это поможет 🙂
Других решений пока нет …