Присваивание выражению с ошибкой типа массива

в этой программе я пытаюсь отсортировать сбережения клиентов по убыванию. И я пытался скомпилировать код. А насчет указателя я до сих пор не понимаю. Ошибка с сообщением «Присваивание выражению с ошибкой типа массива». Целевым результатом этой программы, как правило, являются отсортированные клиенты (с их именами и номерами счетов). Я поискал в Интернете информацию об этой ошибке. Но я все еще не понимаю решения. Может кто-нибудь помочь мне решить ошибку? Спасибо.

#include <stdio.h>
#include <stdlib.h>

struct Data
{
  long long int Savings[100], AccNo[100];
  char Name[100];
};

int main ()
{
  struct Data *ptr;
  int n, i, j, swap = 1, x, y;
  long long int max, min, temp;

  printf ("Enter number of customer(s) : ");
  scanf ("%d", &n);

  ptr = (struct Data *) malloc (n * sizeof (struct Data));

  for (i = 0; i < n; i++)
    {
      printf ("Enter customer %d", i + 1);
      printf ("\nName : ");
      getchar ();
      scanf ("%[^\n]s", &(ptr + i)->Name);
      printf ("Savings : ");
      scanf ("%d", &(ptr + i)->Savings);
      printf ("Account Number : ");
      scanf ("%d", &(ptr + i)->AccNo);
      printf ("\n");
    }

  //Sorting bubblesort
  for (x = 0; x < n; x++)
    {
      for (y = 0; y < (n - x - 1); y++)
    {
      if ((ptr + y)->Savings > (ptr + y + 1)->Savings)
        {
          temp = (ptr + y)->Savings;
          (ptr + y)->Savings = (ptr + y + 1)->Savings;
          (ptr + y + 1)->Savings = temp;
        }
    }
    }

  //Print sorted
  printf ("\n Sorted customers are (:\n");
  for (i = 0; i < n; ++i)
    {
      printf ("%s\n", (ptr + i)->Name);
      printf ("%d\n", (ptr + i)->Savings);
    }
  free (ptr);
  return 0;
}

Сообщение об ошибке пришло с номером строки, не так ли?

Sourav Ghosh 28.11.2018 16:39

А где возникает эта ошибка?

Paul Ogilvie 28.11.2018 16:39

Кроме того, я не думаю, что Savings и AccNo должны быть массивами.

Sourav Ghosh 28.11.2018 16:40
temp = (ptr + y)->Savings; неверен: temp - это long long, но правая сторона - это struct Data *.
Paul Ogilvie 28.11.2018 16:41
scanf("%[^\n]s" попытается прочитать буквально фактический 's'. 'S' не входит в строку преобразования
pmg 28.11.2018 16:41

Ошибка возникает в (ptr + y)->Savings = (ptr + y + 1)->Savings; и (ptr + y + 1)->Savings = temp; @PaulOgilvie

SALOMO 28.11.2018 16:42

В алгоритме пузырьковой сортировки вы пытаетесь сопоставить массив long long int Savings[100] с простым long long int temp. Конечно, пример пузырьковой сортировки, который вы использовали в качестве основы для своего кода, работал с указателями объектов, присваивая указатели указателям, но вы смешиваете массивы и отдельные переменные.

Frankie_C 28.11.2018 16:48
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
1 572
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. Вам нужно скомпилировать свой код с включенными предупреждениями, руководство вы пройдете отладку шаг за шагом. Попытайтесь устранить одного, и снова скомпилировать. Например, в GCC вы должны использовать флаг -Wall.
  2. Числовые поля вашей структуры должны быть просто числами, а не массивы. Более того, их тип как long long int кажется немного слишком много, но я оставляю это на вас.
  3. Наличие (ptr + y)->Savings для доступа к y-му элементу массива структур и их имена полей Savings технически корректны, но он намного чище (что увеличивает читабельность и ремонтопригодность) для записи ptr[y].Savings. Это общее правило, применительно к остальной части вашего кода.
  4. Я считаю, что вышеизложенное привело вас к двум синтаксическим ошибкам, когда вы читали числовые данные клиентов с scanf(), поскольку вы знаете, что целое число обычно требует оператора &. Если вы использовали чистый подход с самого начала, вы бы не сделали те, я полагаю.
  5. Для long long int используйте спецификатор формата %lld, а не только %d.
  6. В Bubblesort, когда вы найдете элементы, которые нужно поменять местами, тогда поменять местами все элементы, а не только их Savings. я рекомендую создание функции для этого.
  7. scanf("%[^\n]s" особого смысла не имеет, я бы поменял на scanf("%99s", где 99 - максимальный размер вашей строки минус один. Подробнее читайте во 2-м абзаце в scanf («% [^ \ n] s», a) вопрос.

Собирая все вместе, получаем:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Data {
    long long int Savings, AccNo; // these should be numbers, not arrays
    char Name[100];
};

void swap(struct Data* a, struct Data* b) {
    struct Data tmp;
    tmp.Savings = a->Savings;
    tmp.AccNo = a->AccNo;
    strcpy(tmp.Name, a->Name);

    a->Savings = b->Savings;
    a->AccNo = b->AccNo;
    strcpy(a->Name, b->Name);

    b->Savings = tmp.Savings;
    b->AccNo = tmp.AccNo;
    strcpy(b->Name, tmp.Name);
}

int main() {
    struct Data *ptr;
    int n, i, x, y;

    printf("Enter number of customer(s) : ");
    scanf("%d", &n);

    ptr = malloc (n * sizeof(struct Data)); // do not cast malloc

    for(i=0; i<n; i++) {
        printf("Enter customer %d", i+1);
        printf("\nName : ");
        getchar();
        scanf("%99s", ptr[i].Name); // ptr is a pointer, but now you want to actually use it as an array, so use '.'
        printf("Savings : ");
        scanf("%lld", &ptr[i].Savings); // needs &, just like you did for 'n'. USe `%lld' for long lont int as the format specifier.
        printf("Account Number : ");
        scanf("%lld", &ptr[i].AccNo);   // needs &, just like you did for 'n'. USe `%lld' for long lont int as the format specifier.
        printf("\n");
    }

    //Sorting bubblesort
    for (x = 0; x < n; x++)
    {
        for (y = 0; y < n - x - 1; y++) // you don't need paranetheses in the stop condition
        {
            if (ptr[y].Savings > ptr[y + 1].Savings)
            {
                swap(&ptr[y], &ptr[y + 1]); // swap the whole element, not just its savings
            }
        }
    }

    //Print sorted
    printf("\nSorted customers are:\n");
    for(i=0; i<n; ++i)
    {
        printf("%s\n", (ptr+i)->Name);
        printf("%lld\n", (ptr+i)->Savings);
    }
    free(ptr);
    return 0;
}

Выход (с соответствующим входом):

Sorted customers are:
George
1
Babis
3
Theodor
20

PS: Могу ли я использовать результат malloc? Нет!

Большое тебе спасибо! Я очень ценю это.

SALOMO 28.11.2018 17:02

@SALOMO добро пожаловать в Stackoverflow! Вы разместили вопрос с MCVE, и это очень хорошо! В следующий раз сделайте также отступ в коде +1! ;)

gsamaras 28.11.2018 17:10

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