Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.05.2020, 09:15   #1
jonikster
Форумчанин
 
Регистрация: 28.10.2014
Сообщений: 216
По умолчанию Односвязный линейный список студентов. Как исправить ошибку?

Здравствуйте.
Нужно создать программу, в которой будет создаваться односвязный линейный список студентов. И нужно сделать возможность изменения имени заданного студента.
При компиляции, выходят ошибки:
Серьезность Код Описание Проект Файл Строка Состояние подавления
Ошибка (активно) E0137 выражение должно быть допустимым для изменения левосторонним значением Student Work C:\Users\John\source\repos\Stu dent Work\Student Work\main.c 87
Ошибка (активно) E1072 объявлению не может быть назначена метка Student Work C:\Users\John\source\repos\Stu dent Work\Student Work\main.c 111
Ошибка C2106 =: левый операнд должен быть левосторонним значением Student Work C:\Users\John\source\repos\Stu dent Work\Student Work\main.c 87

Как можно исправить эти ошибки?
И дополнительно, посоветуйте, как я могу улучшить мой код? Может, что-то можно написать проще, лучше или эффективнее?
Код main.c:
Код:
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define MAX 3
#define KOL 15
*
struct Student
{
* * int id;
* * char Name[KOL];
* * int Age;
* * float AverageRaiting;
* * struct Student* nextStudent;
};
*
void InitStudentList(struct Student** student)
{
* * *student = (struct Student*)
* * * * malloc(sizeof(struct Student));
* * (*student)->id = 1;
* * printf("Введіть ім’я 1-го студента: ");
* * scanf("%s", (*student)->Name);
* * printf("Введіть вік 1-го студента: ");
* * scanf("%d", &(*student)->Age);
* * printf("Введіть середній рейтинг 1-го студента: ");
* * scanf("%f", &(*student)->AverageRaiting);
* * printf("\n");
* * (*student)->nextStudent = NULL;
* * struct Student* endStudent = *student;
* * for (int i = 2; i <= MAX; i++)
* * {
* * * * endStudent->nextStudent =
* * * * * * (struct Student*) malloc(sizeof(struct Student));
* * * * endStudent = endStudent->nextStudent;
* * * * endStudent->id = i;
* * * * printf("Введіть ім’я %d-го студента: ", i);
* * * * scanf("%s", endStudent->Name);
* * * * printf("Введіть вік %d-го студента: ", i);
* * * * scanf("%d", &endStudent->Age);
* * * * printf("Введіть середній рейтинг %d-го студента: ", i);
* * * * scanf("%f", &endStudent->AverageRaiting);
* * * * printf("\n");
* * * * endStudent->nextStudent = NULL;
* * }
}
*
void PrintList(struct Student* student)
{
* * struct Student* printStudent = student;
* * printf("==========================\n");
* * printf("Номер * * * * Ім’я * * * * Вік *Рейтинг \n");
* * printf("==========================\n");
* * while (printStudent)
* * {
* * * * printf("%d", printStudent->id);
* * * * printf("%-15s", printStudent->Name);
* * * * printf("%4d", printStudent->Age);
* * * * printf("%8.2f", printStudent->AverageRaiting);
* * * * printf("\n");
* * * * printStudent = printStudent->nextStudent;
* * }
* * printf("==========================\n");
}
*
void FreeList(struct Student** student)
{
* * if (*student == NULL)
* * * * return;
* * struct Student* tmp = *student;
* * struct Student* curr_stud;
* * while (tmp)
* * {
* * * * curr_stud = tmp;
* * * * tmp = tmp->nextStudent;
* * * * free(curr_stud);
* * }
* * *student = NULL;
}
*
void ChangeStudentName(int n, char name[KOL], struct Student* student)
{
* * struct Student* changingStudent = student;
* * while (changingStudent)
* * {
* * * * if (changingStudent->id == n)
* * * * {
* * * * * * changingStudent->Name = name;
* * * * * * printf("зміни записані");
* * * * * * break;
* * * * }
* * }
}
*
int main(void)
{
* * int command;
* * struct Student* BaseStudent = NULL;
* * SetConsoleCP(1251);
* * SetConsoleOutputCP(1251);
* * InitStudentList(&BaseStudent);
* * for (;;)
* * {
* * * * printf("Введіть команду:\n 1 - Виведення списку студентів,\n 2 - Змінити прізвище зазначеного студента,\n 3 - вихід\n");
* * * * scanf("%d", &command);
* * * * switch (command)
* * * * {
* * * * case 1:
* * * * * * PrintList(BaseStudent);
* * * * * * break;
* * * * case 2:
* * * * * * int n;
* * * * * * char name[KOL];
* * * * * * printf("Введіть номер студента: ");
* * * * * * scanf("%d", &n);
* * * * * * printf("Введіть нове ім'я студента: ");
* * * * * * scanf("%s", &name);
* * * * * * * * ChangeStudentName(n, name, BaseStudent);
* * * * * * break;
* * * * case 3:
* * * * * * FreeList(&BaseStudent);
* * * * * * return 0;
* * * * * * break;
* * * * default:
* * * * * * printf("Помилка вводу...");
* * * * * * FreeList(&BaseStudent);
* * * * * * return 0;
* * * * * * break;
* * * * }
* * }
* * return 0;
}
Заранее благодарен!
jonikster вне форума Ответить с цитированием
Старый 28.05.2020, 09:16   #2
jonikster
Форумчанин
 
Регистрация: 28.10.2014
Сообщений: 216
По умолчанию

Как я понял, здесь ошибка в:
Код:
* * * * * * changingStudent->Name = name;
Но я пока не очень понимаю, как это исправить.
jonikster вне форума Ответить с цитированием
Старый 28.05.2020, 10:27   #3
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

jonikster,

Код:
//это будет работать только для статических массивов
const int size=sizeof(changingStudent->Name);
if(size && size>=sizeof(name))
{
    memcpy(changingStudent->Name,name,size);
    changingStudent->Name[size-1]='\0';
}
Алексей1153 вне форума Ответить с цитированием
Старый 28.05.2020, 10:29   #4
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

Цитата:
Сообщение от jonikster Посмотреть сообщение
И дополнительно, посоветуйте, как я могу улучшить мой код? Может, что-то можно написать проще, лучше или эффективнее?
да, перейти с C на C++ портянка будет раз в 10 меньше
Алексей1153 вне форума Ответить с цитированием
Старый 28.05.2020, 10:39   #5
jonikster
Форумчанин
 
Регистрация: 28.10.2014
Сообщений: 216
По умолчанию

Если я бы мог перейти с C на C++, давно перешел бы. Но увы. Конкретно эту задачу просят на C.
jonikster вне форума Ответить с цитированием
Старый 28.05.2020, 10:48   #6
jonikster
Форумчанин
 
Регистрация: 28.10.2014
Сообщений: 216
По умолчанию

В итоге, у меня после ввода номера студента и нового имени, программа зависает. Даже не пишет, что изменение было произведено.
Код:
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define MAX 10
#define KOL 15

struct Student
{
    int id;
    char Name[KOL];
    int Age;
    float AverageRaiting;
    struct Student* nextStudent;
};

void InitStudentList(struct Student** student)
{
    *student = (struct Student*)
        malloc(sizeof(struct Student));
    (*student)->id = 1;
    printf("Введіть ім’я 1-го студента: ");
    scanf("%s", (*student)->Name);
    printf("Введіть вік 1-го студента: ");
    scanf("%d", &(*student)->Age);
    printf("Введіть середній рейтинг 1-го студента: ");
    scanf("%f", &(*student)->AverageRaiting);
    printf("\n");
    (*student)->nextStudent = NULL;
    struct Student* endStudent = *student;
    for (int i = 2; i <= MAX; i++)
    {
        endStudent->nextStudent =
            (struct Student*) malloc(sizeof(struct Student));
        endStudent = endStudent->nextStudent;
        endStudent->id = i;
        printf("Введіть ім’я %d-го студента: ", i);
        scanf("%s", endStudent->Name);
        printf("Введіть вік %d-го студента: ", i);
        scanf("%d", &endStudent->Age);
        printf("Введіть середній рейтинг %d-го студента: ", i);
        scanf("%f", &endStudent->AverageRaiting);
        printf("\n");
        endStudent->nextStudent = NULL;
    }
}

void PrintList(struct Student* student)
{
    struct Student* printStudent = student;
    printf("==========================\n");
    printf("Номер         Ім’я         Вік  Рейтинг \n");
    printf("==========================\n");
    while (printStudent)
    {
        printf("%d", printStudent->id);
        printf("%-15s", printStudent->Name);
        printf("%4d", printStudent->Age);
        printf("%8.2f", printStudent->AverageRaiting);
        printf("\n");
        printStudent = printStudent->nextStudent;
    }
    printf("==========================\n");
}

void FreeList(struct Student** student)
{
    if (*student == NULL)
        return;
    struct Student* tmp = *student;
    struct Student* curr_stud;
    while (tmp)
    {
        curr_stud = tmp;
        tmp = tmp->nextStudent;
        free(curr_stud);
    }
    *student = NULL;
}

void ChangeStudentName(int n, char name[KOL], struct Student* student)
{
    struct Student* changingStudent = student;
    while (changingStudent)
    {
        if (changingStudent->id == n)
        {
            const int size = sizeof(changingStudent->Name);
            if (size && size >= sizeof(name))
            {
                memcpy(changingStudent->Name, name, size);
                changingStudent->Name[size - 1] = '\0';
            }
            printf("зміни записані");
            break;
        }
    }
}

int main(void)
{
    int command;
    struct Student* BaseStudent = NULL;
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    InitStudentList(&BaseStudent);
    for (;;)
    {
        printf("Введіть команду:\n 1 - Виведення списку студентів,\n 2 - Змінити ім'я зазначеного студента,\n 3 - вихід\n");
        scanf("%d", &command);
        switch (command)
        {
        case 1:
            PrintList(BaseStudent);
            break;
        case 2:
        {
            int n;
            char name[KOL];
            printf("Введіть номер студента: ");
            scanf("%d", &n);
            printf("Введіть нове ім'я студента: ");
            scanf("%s", &name);
            ChangeStudentName(n, name, BaseStudent);
            break;
        }
        case 3:
            FreeList(&BaseStudent);
            return 0;
            break;
        default:
            printf("Помилка вводу...");
            FreeList(&BaseStudent);
            return 0;
            break;
        }
    }
    return 0;
}
jonikster вне форума Ответить с цитированием
Старый 28.05.2020, 10:52   #7
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

Цитата:
Сообщение от jonikster Посмотреть сообщение
программа зависает.
отладчик в руки - и вперёд
Алексей1153 вне форума Ответить с цитированием
Старый 28.05.2020, 10:54   #8
jonikster
Форумчанин
 
Регистрация: 28.10.2014
Сообщений: 216
По умолчанию

Я попробовал сделать так:
Код:
strcpy(changingStudent->Name,name);
Та же ситуация.
jonikster вне форума Ответить с цитированием
Старый 28.05.2020, 10:59   #9
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 960
По умолчанию

Цитата:
Сообщение от jonikster Посмотреть сообщение
strcpy
в данном случае хуже - у тебя нет гарантии, что строки z-терминированы

вряд ли на "зависание" влияет это копирование, ошибка где-то в другом месте. С помощью отладчика это можно выяснить


чисто визуально вот тут косяк

void ChangeStudentName(int n, char name[KOL], struct Student* student)
{
struct Student* changingStudent = student;
while (changingStudent) // это условие будет всегда выполняться, если указатель не нулевой
{
....
}
}

Последний раз редактировалось Алексей1153; 28.05.2020 в 11:01.
Алексей1153 вне форума Ответить с цитированием
Старый 28.05.2020, 11:04   #10
jonikster
Форумчанин
 
Регистрация: 28.10.2014
Сообщений: 216
По умолчанию

Мне нужно, чтобы цикл шел по массиву, пока не найдет заданный номер студента. Разве это не вариант? Как тогда я могу пройтись по массиву?
jonikster вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Линейный односвязный список на Си Enni Помощь студентам 24 28.03.2016 18:11
Односвязный линейный список flecso Паскаль, Turbo Pascal, PascalABC.NET 1 13.05.2012 02:51
С++ линейный односвязный список Lady IcE Помощь студентам 3 25.04.2011 20:24
Линейный-односвязный список Айдар Помощь студентам 1 01.06.2010 10:20
линейный односвязный список на С - что это?? о_О aka_Kiss Помощь студентам 8 22.12.2009 01:39