Ошибка c3863 тип массива char 20 является неназначаемым

13 / 9 / 3

Регистрация: 06.01.2015

Сообщений: 62

1

14.01.2017, 13:56. Показов 17431. Ответов 2


Студворк — интернет-сервис помощи студентам

Доброго всем времени суток, вопрос у меня такой что это за ошибка такая (C3863 тип массива «char [40]» является неназначаемым), я сам никак догнать не могу. Я не так давно начал постигать С++ поэтому мой вопрос кому-то может показаться глупым, а решение оказаться очевидным, прошу камнями не кидать Возникает эта ошибка при выполнении самостоятельного задания из учебника, в котором дан листинг заголовочного файла и необходимо написать определения функций и программу использующую все функции из заголовочного файла.

Код программы:

Кликните здесь для просмотра всего текста

golf.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
const int LEN = 40;
struct golf
{
    char fullname[LEN];
    int handicap;
};
// Неинтерактивная версия:
//  функция присваивает стректуре типа golf имя игрока и его гандикап (фору),
//  используя передаваемые ей аргументы
void setgolf(golf & g, const char * name, int hc);
// Интерактивная версия:
//  функция предлагает пользователь ввести имя и гандикап,
//  присваивает элементам структуры g введенные значения;
//  возвращает 1, если введено имя, и 0, если введена пустая строка
int setgolf(golf & g);
// Функция устанавливает новое значение гандикапа
void handicap(golf & g, int hc);
// Функция отображает содержимое скруктуры типа golf
void showgolf(const golf & g);

golf.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include "golf.h"
 
void setgolf(golf & g, const char * name, int hc)
{
    g.fullname = name;
    g.handicap = hc;
}
 
int setgolf(golf & g)
{
    using std::cout;
    using std::cin;
 
    char name[LEN];
    int hc;
    cout << "Enter name: ";
    cin.getline(name, LEN);
    if (strlen(name) == 0) return 0;
    cout << "Enter handicap: ";
    (cin >> hc).get();
    setgolf(g, name, hc);
    return 1;
}
 
void handicap(golf & g, int hc)
{
    g.handicap = hc;
}
 
void showgolf(const golf & g)
{
    using std::cout;
    using std::endl;
 
    cout << "Name:\t\t" << g.fullname << endl
         << "Handicap:\t" << g.handicap << endl;
}

pe9-1.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include "golf.h"
 
const int SIZE = 4;
 
int main()
{
    using std::cout;
    using std::cin;
 
    int n = 0;
    golf arr[SIZE];
    cout << "Fill:\n";
    for (int i = 0; i < SIZE; i++, n++)
    {
        if (!setgolf(arr[i])) break;
    }
    if (n != 0)
    {
        cout << "View:\n";
        for (int i = 0; i < n; i++)
            showgolf(arr[i]);
        cout << "Change handicaps:\n";
        for (int i = 0, hc; i < n; i++)
        {
            cout << arr[i].fullname << ": ";
            cin >> hc;
            handicap(arr[i], hc);
        }
        cout << "View:\n";
        for (int i = 0; i < n; i++)
            showgolf(arr[i]);
    }
    return 0;
}

Если подключить в заголовочном файле string, и заменить в структуре golf переменную char fullname[LEN]; на string fullname; то все работает как положено но в задании сказано используя именно заголовочный файл из листинга. Помогите разобраться, заранее спасибо всем откликнувшимся.



0



Ну вот мой первый пост. Я пытался сделать этот выбор, и я хочу, чтобы пользователь выбирал только цифры вместо того, чтобы вводить их (проще), но когда я хочу, чтобы числа были равны строке, он говорит: «Тип массива char[30] не может быть назначен». Даже если на спине я помещаю полуточку или нет.

#include <stdio.h>

int main() {
  int choice1;
  char word[30];

  printf("You have three choice.\n");
  printf("[1] Jump [2] Run [3] Dance\n");
  scanf("%d",&choice1);
  if (choice1 == 1)
  {
    word = "Jump" //Error #1
  }
  else if (choice1 == 2)
  {
    word = "Eat" //Error #2
  }
  else if (choice1 == 3)
  {
    word = "Sleep"; //Error #3
  }

  printf("You will now be %sing",word);

}

4b9b3361

Ответ 1

Вы не можете назначить массив, только скопируйте его.

Используйте strcpy, например

strcpy(word, "Jump");

Ответ 2

TL; DR ответ: имя массива не изменчивое значение lvalue. Таким образом, вы не можете использовать оператор присваивания (=).

Чтобы скопировать содержимое в массив, вам нужно использовать strcpy() из массива string.h (char) или memcpy() в целом.


Теперь, чтобы выяснить фактическую причину сообщения об ошибке, процитировав C11, главу §6.5.16, Assignment operators

оператор присваивания должен иметь изменяемое значение lvalue в качестве его левого операнда.

а затем, цитируя главу §6.3.2.1 из того же стандарта,

Модифицируемое lvalue является lvalue, не имеющим тип массива, [….]

Таким образом, имя массива не является изменяемым значением lvalue, следовательно, вы не можете назначить ему что-либо. Это является причиной сообщения об ошибке.

Ответ 3

Оператор = не может использоваться для копирования содержимого одного массива в другой; вы должны использовать библиотечную функцию типа strcpy или strcat для строк, memcpy для не-строк (или отдельно назначать элементы массива).

Это следствие того, как C обрабатывает выражения массива. Выражение массива определяется стандартом языка как немодифицируемое значение lvalue; это значение lvalue, потому что оно относится к объекту в памяти, но оно не может быть целью назначения.

Операция подстроки массива a[i] определяется как *(a + i); то есть с учетом адреса массива a, смещения i элементов из этого адреса и разыменования результата. Поскольку выражение массива a рассматривается как указатель, большинство людей думает, что переменная a хранит указатель на первый элемент массива, но это не так. Все, что хранится, — это сами элементы массива.

Вместо этого, всякий раз, когда компилятор видит выражение в выражении в выражении, он преобразует это выражение из типа «N-element array of T» в «указатель на T«, а значение выражения становится адресом из первого элемента массива (если выражение не является операндом операторов sizeof или унарных &, или является строковым литералом, используемым для инициализации другого массива в объявлении).

И вот почему выражение массива типа word не может быть целью назначения; там нечего назначать. Нет объекта word, который существует независимо от word[0], word[1] и т.д.

Когда вы пишете

word = "Jump";

тип выражения "Jump" преобразуется из «5-элементного массива char» в «указатель на char«, а значение выражения — это адрес первого элемента массива. И вы пытаетесь присвоить это значение указателю объекту массива, который a) не является указателем, а b) не может быть назначен в любом случае.

Ответ 4

Используйте stcpy от <string.h>

 strcpy(word,"Jump");

И аналогичный для остальных из них.

Вы просто не можете сделать word ="Jump". Поскольку содержимое модифицируется, сами массивы не являются.

У меня есть метод шаблона, в котором я пытаюсь поместить объекты в массив. Я продолжаю получать ошибку названия все же. Ниже мой следующий код:

template <class Object>
void SparseMat<Object>::showSubSquare(int start, int size) {
for (int rowIndex = start; rowIndex < start + size; rowIndex++) {
Object objectsInRow[size];
FHlist<MatNode<Object>> wantedRow = matrix[rowIndex];
for (iterator<MatNode<Object>> iter = wantedRow.begin(); iter != wantedRow.end(); ++iter) {
MatNode<Object> m = *iter;
objectsInRow[m.getCol()] = m.data; //ERROR
}
for (int colIndex = start; colIndex < start + size; rowIndex++) {
if (objectsInRow[colIndex] == NULL) {
cout << defaultValue << " ";
}
else {
cout << objectsInRow[colIndex] << " ";
}
}
cout << endl;
}
}

Для справки, m.getCol () просто возвращает int, так что это не вызывает ошибку. Кроме того, матрица — это вектор списков, а FHlist — это самореализуемый список с той же базовой утилитой.

Я использую функцию шаблона следующим образом:

typedef SparseMat<float> SpMat;

int main()
{
SpMat mat(MAT_SIZE, MAT_SIZE, 0);

mat.showSubSquare(0, 15);
}

Точная ошибка: «ошибка C3863: тип массива ‘float [size]’ не может быть назначен»

-2

Решение

«размер» не является константой во время компиляции, это вызовет сбой;

План А:

Измените это с помощью std :: vector,

План б:

используя «новый тип [размер]»

План C:

template <int _size> // this is the const value for the compiling time
void func()
{
type array[_size];
// your code ...
}

0

Другие решения

Других решений пока нет …

Одной из наиболее популярных интегрированных сред разработки с++, используемых разработчиками, является Visual Studio 2017. В процессе работы с этой средой могут возникать различные ошибки и предупреждения, которые могут привести к проблемам в ходе написания кода. Одной из таких ошибок является С3863, которая указывает на то, что тип массива является неназначаемым.

Данная ошибка возникает, когда разработчик пытается назначить значение массива другому массиву, что является недопустимым в языке c++. Обычно эта ошибка возникает при попытке копирования массива или при передаче массива в функцию.

Прежде чем начать разбираться с этой ошибкой, давайте рассмотрим пример кода, который может привести к возникновению данной ошибки:

#include <iostream>

void CopyArray(int* arr1, int* arr2, int size)
{
    for (int i = 0; i < size; i++)
    {
        arr2[i] = arr1[i];
    }
}

int main()
{
    int arr1[] = { 1, 2, 3, 4, 5 };
    int arr2[] = { 0, 0, 0, 0, 0 };

    CopyArray(arr1, arr2, sizeof(arr1) / sizeof(int));

    return 0;
}
[/code]

В данном примере у нас есть функция CopyArray, которая принимает два указателя на массивы arr1 и arr2, а также размер массива size. Функция копирует элементы из arr1 в arr2. В функции main мы объявляем два массива arr1 и arr2, и вызываем функцию CopyArray.

Однако, при компиляции этого кода в Visual Studio 2017, мы получим ошибку С3863: "тип массива является неназначаемым" на строке, где происходит попытка копирования элементов массива.

Почему возникает данная ошибка? Ответ на этот вопрос кроется в том, что в языке c++ массивы считаются типом, который не может быть назначен (assigned). Это означает, что при попытке присвоить значение одного массива другому массиву, произойдет ошибка компиляции.

Теперь, когда мы понимаем, почему возникает данная ошибка, давайте рассмотрим, как ее исправить. 

Один из вариантов исправления данной ошибки - использовать цикл для присвоения каждого элемента массива вручную. Ниже приведен исправленный код:


[code]#include <iostream>

void CopyArray(int* arr1, int* arr2, int size)
{
    for (int i = 0; i < size; i++)
    {
        arr2[i] = arr1[i];
    }
}

int main()
{
    int arr1[] = { 1, 2, 3, 4, 5 };
    int arr2[] = { 0, 0, 0, 0, 0 };

    int size = sizeof(arr1) / sizeof(int); // вычисляем размер массива

    for (int i = 0; i < size; i++) // присваиваем каждый элемент массива вручную
    {
        arr2[i] = arr1[i];
    }

    return 0;
}
[/code]

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

Теперь код должен компилироваться без ошибок. Однако это просто самый простой способ исправить данную ошибку. В некоторых случаях может потребоваться более сложное решение, особенно если у вас есть большой и сложный массив, который вы хотите скопировать.

Помимо использования цикла, существует также несколько других подходов, которые можно использовать для копирования массивов в языке c++. Один из таких подходов - использование стандартной библиотеки шаблонов STL, которая предоставляет функции и алгоритмы для работы с массивами и контейнерами.

Вот пример использования функции std::copy из библиотеки STL для копирования массива:


[code]#include <iostream>
#include <algorithm>

int main()
{
    int arr1[] = { 1, 2, 3, 4, 5 };
    int arr2[] = { 0, 0, 0, 0, 0 };

    int size = sizeof(arr1) / sizeof(int); // вычисляем размер массива

    std::copy(arr1, arr1 + size, arr2); // используем функцию std::copy для копирования массива

    return 0;
}

В этом примере мы используем функцию std::copy из библиотеки STL для копирования элементов из массива arr1 в массив arr2. Функция std::copy принимает итераторы на начало и конец исходного диапазона, а также итератор на начало целевого диапазона. Она копирует все элементы из исходного диапазона в целевой диапазон.

Использование функции std::copy позволяет нам избежать проблемы с неназначаемыми типами массивов, которая может возникать при использовании цикла для копирования массива.

Очень важно знать, как работать с ошибками в Visual Studio 2017 при разработке на языке c++. Ошибка С3863, связанная с неназначаемыми типами массивов, является одной из таких ошибок, с которыми могут столкнуться разработчики. Она указывает на несовместимость операции присвоения между двумя массивами, что может привести к непредсказуемым результатам.

В этой статье мы рассмотрели причины возникновения ошибки С3863 в Visual Studio 2017 и предложили несколько способов ее исправления. Мы показали, что использование цикла и функции std::copy из библиотеки STL являются двумя возможными способами решения этой проблемы.

Разработка на языке c++ требует аккуратного отношения к ошибкам и их исправлению. Надеюсь, что данная статья поможет вам понять, как обрабатывать ошибку С3863 и предоставит вам инструменты для ее исправления в Visual Studio 2017.

Формулировка задачи:

Имеется вот такая вот программа

Её нужно переделать так, чтобы в main остался только ввод и вывод строки, а всё остальное было в отдельной функции Я сделал это вот так

При компиляции VS выдаёт ошибку «тип массива «char [200]» является неназначаемым» и указывает на строку «newstr = words_in_reverse(str)» Как это можно исправить? Программа должна при вводе строки выводить строку пословно, буквы в словах должны быть в обратном порядке. Сама программа работает, но как переделать это всё в функцию, я не понимаю

Код к задаче: «Тип массива «char [200]» является неназначаемым»

textual

void getStr(void);
void printStr(void);

Полезно ли:

9   голосов , оценка 3.667 из 5

Понравилась статья? Поделить с друзьями:
  • Ошибка c3825 konica minolta
  • Ошибка c3861 идентификатор не найден
  • Ошибка c3472 газель
  • Ошибка c3425 konica
  • Ошибка c3300 kyocera 3501i