Я не понимаю синтаксис, необходимый для динамического размещения членов структуры в C ++. По сути, мне нужно заполнить члены массива char до точного размера, используя временный массив и strlen. Вот моя структура:
struct card
{
char *rank;
char *suit;
char color;
bool dealt;
char *location;
};
Вот функция, которая использует структуру:
bool importCard(card *deckPtr, char *deckName);
Я создал массив из 52 карточек, назначил на него указатель и передал его функции в качестве первого параметра. (deckPtr) Вот цикл в функции, который должен считывать информацию карты для членов структуры данных.
for(index=0;index<52;index++,deckPtr++)
{
fin >> *temp;
charCount=stringLength(temp);
deckPtr.*rank = new char[charCount+1];
stringCopy(*temp, deckPtr.*rank);
fin >> *temp;
charCount=stringLength(temp);
deckPtr.*suit = new char[charCount+1];
stringCopy(*temp, deckPtr.*suit);
if(deckPtr.*suit==('d')||deckPtr.*suit==('h'))
{
(*deckPtr).color='r';
}
else
{
(*deckPtr).color='b';
}
(*deckPtr).dealt=false;
deckPtr.*location = new char[11];
stringCopy(unshPtr, deckPtr.*location);
}
Я получаю три ошибки компиляции: «rank», «suit» и «location» не «объявлены в этой области». Что я делаю неправильно? Спасибо!
Синтаксис deckPtr->rank
, deckPtr->suit
, deckPtr->location = new char[...];
,
Но ваш стиль кодирования больше похож на C, чем на C ++. Вместо этого, если вы используете современный C ++, с удобными классами RAII, такими как std::string
, ваш код становится намного больше упрощенный: просто используйте std::string
вместо сырья char*
указатели, и вам не нужно обращать внимание на выделение памяти и освобождение памяти: все это автоматически управляется std::string
и деструкторы.
#include <string>
struct card
{
std::string rank;
std::string suit;
char color;
bool dealt;
std::string location;
};
И вместо твоего обычая stringCopy()
Функция, которую вы можете просто использовать «естественный» operator=
перегрузка для std::string
(Т.е. destString = sourceString;
).
И чтобы построить массив из 52 карт, просто используйте std::vector
:
#include <vector>
std::vector<card> cards(52);
Опять же, распределение памяти автоматически управляется std::vector
(и, в отличие от необработанных массивов C, вы можете запросить vector
для собственного количества элементов, используя его size()
метод).
Вы, вероятно, хотите использовать deckPtr->rank
, deckPtr->suit
, а также deckPtr->location
назначить что-то char
указатели (альтернативно, (*deckPtr).rank
так далее.). Обратите внимание, что *
в char *var
не является частью имени переменной. Он просто утверждает, что переменная является указателем на char
,
Тебе нужно deckPtr->foo
вместо deckPtr.*foo
Ваша проблема в том, что оператор разыменования работает на foo
, не на deckPtr
, что делает не имеет смысла компилятору C ++, поэтому он использует вместо указатель на член оператора. Этот оператор используется для выполнения указателей на функции-члены на объекте, который полностью отличается от доступа к члену. Скорее всего, во вводном классе c ++ (как вы, кажется, находитесь) вам никогда не придется беспокоиться об использовании или понимании этого оператора.
В общем, в C / C ++ всякий раз, когда у вас есть указатель на структуру, вы хотите использовать ->
оператор, а не .
, foo->bar
эквивалентно (*foo).bar
, но это мешает вам испортить и забыть скобки. Есть причина, по которой у C был оператор со стрелкой — это проще и понятнее. По моему не столь скромному мнению, учителя, которые налагают такие произвольные ограничения, на самом деле учат студентов писать плохой код и заново изобретать колеса, но у меня нет опыта преподавания программирования …