С++, как передать массив строк в функцию и присвоить переменной?

Я получил эту ошибку при кодировании простой функции. Это моя спецификация функции.

string studentName;
string courseTaken[3];
void setStudent(string, string[]); 

void Student::setStudent(string n, string a[])
{
   studentName= n;
   courseTaken = a;
}

Это ошибка, которую я получил:

несовместимые типы при присвоении строки* строке [3] в этой строке courseTaken = a;

В моем коде я никогда не объявлял никаких указателей или символов.

Я не совсем понимаю, что здесь происходит.


person Einn Hann    schedule 01.04.2018    source источник
comment
Используйте std::array или std::vector. Это не Ц.   -  person user202729    schedule 01.04.2018
comment
Спецификацию предоставил преподаватель. Можете подробнее объяснить, что подразумеваете под этим не C?   -  person Einn Hann    schedule 01.04.2018
comment
Возможный дубликат Ошибка C++: несовместимые типы при назначении из 'char*' в 'char [2]   -  person user202729    schedule 01.04.2018
comment
Пожалуйста, опубликуйте достаточно класса, чтобы сделать полный компилируемый пример, демонстрирующий ошибку.   -  person Galik    schedule 01.04.2018
comment
Таким образом, в С++ для массива я не могу просто присвоить массив таким образом. Мне нужно сделать copy -> std::copy(std::begin(foo), std::end(foo), std::begin(bar));   -  person Einn Hann    schedule 01.04.2018
comment
Массивы C так не работают. Когда вы передаете его функции, вы просто передаете указатель на первый элемент вокруг. Объявление функции точно такое же, как void Student::setStudent(string n, string *a). Под этим не C, @user202729 означает, что вы должны использовать контейнеры C++ вместо массивов C, в которых есть некоторые неинтуитивные вещи, особенно когда вы пытаетесь передать их функции. Он / она, вероятно, имеет в виду распространенную плохую практику обучения материалам C перед материалами C++.   -  person BessieTheCookie    schedule 01.04.2018
comment
Честно говоря, в C++ вашей функции было бы лучше, если бы она была шаблоном и принимала диапазон итератора в качестве аргументов. Так работает большая часть стандартной библиотеки, и не без причины. Если вы не собираетесь добавлять аргумент (а вы это сделаете, потому что прямо сейчас функция не знает, сколько элементов находится в последовательности a[], вы можете подумать о том, чтобы сделать это правильно.   -  person WhozCraig    schedule 01.04.2018
comment
И std::copy(std::begin(foo), std::end(foo), std::begin(bar)); не сработает, потому что при передаче массивов в функции не передается информация о размере массива. Массивы C также не имеют функций begin() и end(), поэтому вам действительно нужно выполнять арифметические операции с указателями. В конце концов, просто используйте контейнеры C++.   -  person BessieTheCookie    schedule 01.04.2018
comment
Перефразируя Йоду: C++. Или С++ нет. Нет попытки. Вы же не хотите прослыть программистом на C+, той странной породой, которая так и не перешла с C на C++ :-)   -  person paxdiablo    schedule 01.04.2018
comment
Потому что спецификацию дал лектор. Фэй Сян, спасибо за объяснение. Я понимаю уже.   -  person Einn Hann    schedule 01.04.2018
comment
Возможно, вы могли бы придумать хитрый способ заставить своего инструктора посмотреть это видео: youtu.be/YnWhqhNdYyk   -  person Jive Dadson    schedule 01.04.2018
comment
Что такое string? std::string?   -  person Jive Dadson    schedule 01.04.2018
comment
Что вы можете изменить, а что, по мнению инструктора, менять нельзя? Если вы ничего не можете изменить, вы ничего не можете исправить.   -  person Jive Dadson    schedule 01.04.2018


Ответы (3)


Вы не можете назначить массив строк string a[] массиву courseTaken с помощью оператора =. Выражение string a[] эквивалентно std::string*. Вот почему вы получаете ошибку компилятора.

Это может быть то, что вы хотели:

#include <iostream>
using namespace std;

class Student
{
    public:
        string studentName;
        string courseTaken[3];
        void setStudent(string n, string a[]); 
};

void setStudent(string n, string a[]); 

void Student::setStudent(string n, string a[])
{
   studentName = n;
   for(int i=0; i < sizeof(courseTaken)/sizeof(courseTaken[0]); i++)
    courseTaken[i] = a[i];
}

int main()
{
    Student student;

    string courses[3] = {"Cobol","C++","Fortran"};
    student.setStudent("Eva", courses);

    for (int i = 0; i < 3; i++){
        cout << student.courseTaken[i] << endl;
    }

    return 0;
}

Выход:

Cobol                                                                                                                                        
C++                                                                                                                                          
Fortran 
person sg7    schedule 01.04.2018

Кажется, вы не понимаете механизм массива decay массивов C-формата. Во многих контекстах имя массива будет объясняться как указатель на первый элемент массива. И этот указатель является prvalue, который, как и указатель this, вы НЕ можете назначить ему. «современный способ Cpp» (С++ 11) заключается в использовании std::array, который перегружает =operator и сохраняет размер массива, чтобы он не разрушался при передаче функции. Второй способ - передать ссылку, с помощью template вы можете убедиться в размере массива, а затем использовать std::memcpy. И вы можете добавить параметр, хранящий размер массива, а затем вы также можете использовать memcpy. Надеюсь, вы воспользуетесь первым способом, не забудьте -std=c++11

person John Ding    schedule 01.04.2018

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

void Student::setStudent(string n, string* a)
{
   studentName= n;
   courseTaken = a;
}
person Hasnain Hayder    schedule 01.04.2018