2016-03-12 2 views
2

У меня возникла проблема с добавлением данных в связанный список. Эти коды в основном пытаются сначала вставить новое имя курса в структуру, а затем вставить структуру в связанный список, и цикл повторяется. Пользователь должен ввести новое название курса.Перемещенные данные связанного списка

Проблема теперь в том, когда пользователь переходит к курсу добавления курса с помощью scanf, он всегда перезаписывает существующее имя курса в связанном списке и добавляет в него.

Это вход и выход из консольного приложения:

Enter operation: 1 
Add Course: asdgvsdrgf 
Enter operation: 1 
Add Course: ehtyerdc 
Enter operation: 1 
Add Course: nbcnvbergt 
Enter operation: 5 (// Just Print course name in the linked list) 
Current enrolments: 
nbcnvbergt 
nbcnvbergt 
nbcnvbergt 

Current enrolments: 

(Изменение ч файлов невозможно, так как это требование об уступке от университета)

Здесь являются с и ч файл прилагается ниже:

bst.h

#pragma once 

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

typedef struct bstNode { 
long student_id; 
struct bstNode *left; 
struct bstNode *right; 
} *BST; 

courselist.h

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

typedef struct course { 
char *name; 
BST students; 
} Course; 

typedef struct courseNode { 
Course data; 
struct courseNode *next; 
} *CourseList; 

bst.c

(not yet written) 

courselist.c

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

void print_course_and_num_students(CourseList *self) { 
CourseList current = *self; 
while (current != NULL) 
{ 
    printf("%s\n", (current->data).name); 
    current = current->next; 
} 
printf("\n"); 
} 

void insert_course_at_front(CourseList *self, Course data) { 
CourseList newNode = (CourseList)malloc(sizeof(struct courseNode)); 

if (*self == NULL) 
{ 
    *self = newNode; 
    (*self)->data = data; 
    (*self)->next = NULL; 
    return; 
} 

    newNode->data = data; 
    newNode->next = *self; 
    *self = newNode; 
} 

main.c

#include <stdio.h> 
#include "courselist.h" 
#include "bst.h" 
#include <stdlib.h> 
#include <cstdbool> 

#define MAX_LEN 100 

void main() 
{ 
CourseList my_course = (CourseList)malloc(sizeof(struct courseNode)); 
my_course = NULL; 
Course my_list; 
(&my_list)->name = (char *)malloc(100 * sizeof(char)); 

bool program_quit = false; 
int input_op; 

char *insert_course_word; 
insert_course_word = (char *)malloc(100 * sizeof(char)); 

char *delete_course_word; 
delete_course_word = (char *)malloc(100 * sizeof(char)); 

do 
{ 
    printf("Enter operation: "); 
    scanf("%d", &input_op); 

    switch (input_op) 
    { 
    case 0:   // Quit 
     program_quit = true; 
     break; 

    case 1:   // Add Course 
     program_quit = false; 
     printf("Add Course: "); 
     scanf("%s", (&my_list)->name); 

     //(&my_list)->name = (insert_course_word); 

     insert_course_at_front(&my_course, my_list); 
     break; 

    case 2:   // Remove Course 
     program_quit = false; 
     printf("Remove Course: "); 
     scanf("%s", delete_course_word); 
     (&my_list)->name = (delete_course_word); 
     delete_course(&my_course, my_list); 
     break; 

    case 3:   // Enrol Student 
     program_quit = false; 
     break; 

    case 4:   // Un-enrol student 
     program_quit = false; 
     break; 

    case 5:   // Print a summary of courses and the number of students enrolled in each course 
     program_quit = false; 
     printf("Current enrolments:\n"); 
     print_course_and_num_students(&my_course); 
     break; 

    case 6:   // Print an ordered list of students enrolled in a course 
     program_quit = false; 
     break; 

    case 7:   // Print a list of courses that a given student is enrolled in 
     program_quit = false; 
     break; 

    default: 
     printf("Invalid operation\n"); 
    } 
} while (program_quit == false); 

if (my_course != NULL) 
{ 
    destroy(&my_course); 
} 

//destroy(&my_list); 
return; 
} 
+0

Вы можете удалить специальный случай 'if (* self == NULL)' при вставке спереди; обычный код будет работать для нулевой главы. –

+0

Спасибо, но проблема все еще существует. В main.c для корпуса коммутатора 1: когда пользователь продолжает вводить новое имя курса, он просто перезапишет предыдущее имя и добавит новый. Например: пользовательский вход 1: abc123, второй вход : poiu123. Однако в связанном списке он просто покажет poiu123 и poiu123, что совершенно неверно. –

+0

Вы использовали отладчик, чтобы найти свою проблему. – MikeMB

ответ

1

Проблема заключается в том, что вы никогда не создать новое имя , но указатели имен всех указателей курса указывают на ту же область памяти, которую вы выделяете в начале main.

Это должно сделать это (Уоринг непроверенного):

program_quit = false; 
printf("Add Course: "); 
char* name = malloc(100 * sizeof(char)); 
scanf("%s", name);  
my_list.name=name; 
insert_course_at_front(&my_course, my_list); 

Однако я хотел бы предостеречь от написания такого кода в любых вопросах, связанные с производством коды. Если пользователь вводит более 100 символов, вы получаете поврежденную память, и если он вводит меньше, вы теряете память. Я думаю, что в C (я долгое время писал код качества работы с кодом качества) вы обычно читали входной символ по символу в локальный буфер (останавливаясь, когда либо буфер заполнен, либо вы получаете, например, новую строку) а затем распределите кусок памяти соответствующего размера и, наконец, скопируйте строку в выделенный фрагмент памяти.

+0

Yup Я согласился с тобой. Мне нужно создать новый 'my_list', добавив новый курс в' my_course' Я не уверен, как это сделать, поскольку я относительно новичок в языке C, особенно в структуре данных. –

+0

@PangYiYang: Я добавил непроверенный кусок кода, который должен делать то, что вы хотите – MikeMB

+0

Да, ваш код работает! Спасибо большое! Не беспокойтесь о 100 символах, мое задание заявило, что ограничение ввода-вывода не должно превышать 100 символов. –

0

Изменить

typedef struct course { 
char *name; 
BST students; 
} Course; 

в

typedef struct course { 
char name[MAX_LEN]; 
BST students; 
} Course; 

иметь некоторое пространство, чтобы разместить название

EDIT - На новой информации

Course new_course; 
    new_course-> name = malloc(MAX_LEN); 

    scanf("%s", new_course->name); // This could be better to prevent buffer overwrite 
    insert_course_at_front(&my_course, new_course); 
+0

Спасибо за предложение, однако мне НЕ разрешено ничего менять из файлов h, поэтому это не вариант. (мое назначение будет оштрафовано на неудачу) –

+0

Вместо этого 'malloc' строка для' name' (извините, но мой хрустальный шар используется рядом с ведьмой) –

+0

Проблема программы заключается не в памяти управление строкой (я исправил ее с помощью malloc вместо MAX_LEN) Теперь в main.c, для корпуса коммутатора 1: когда пользователь продолжает вводить новое имя курса, он просто перезапишет предыдущее имя, а также добавит новое Например: 1-й вход: abc123, 2-й вход: poiu123. Однако в связанном списке он просто покажет poiu123 и poiu123. –

Смежные вопросы