При вводе второго ключа с информацией выводится ошибка - C (СИ)
Формулировка задачи:
Всем привет подскажите где косяк, заказал программу) у исполнителя она работает у меня нет, уже на куче машин пытался запустить. При вводе второго ключа с информацией выводит ошибку
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int SIZE = 10;
typedef struct List
{
int key;
char *info;
struct List *next;
} TList;
int currentSize = 0;
struct List* backInsert( struct List *lst, int k, char *s )
{
TList *ins = ( TList* )malloc( sizeof( TList ) );
ins -> info = ( char* )malloc( 150 );
strcpy( ins -> info, s );
ins -> key = k;
if ( lst == NULL )
{
currentSize = 1;
lst = ins;
}
else
{
TList *pointer = lst;
while ( pointer -> next != NULL )
{
if ( pointer -> key == k && ( strcmp( pointer -> info, s ) == NULL ) )
{
printf( "Error inserting!\n" );
return NULL;
}
pointer = pointer -> next;
}
if ( currentSize + 1 > SIZE )
{
printf( "Overflow! > SIZE\n" );
return lst;
}
currentSize++;
pointer -> next = ins;
}
return lst;
}
TList* removeItem( TList *lst, int k )
{
TList *pointer = lst, *pnt;
int wasRemoved = 0;
while ( pointer != NULL )
{
if ( pointer -> key == k )
{
if ( pointer == lst )
{
lst = lst -> next;
free( pointer );
pointer = lst;
}
else
{
pnt -> next = pointer -> next;
free( pointer );
pointer = pnt -> next;
}
wasRemoved = 1;
}
else
{
pnt = pointer;
pointer = pointer -> next;
}
}
if ( wasRemoved == 0 )
printf( "Item with key %d not removed!\n", k );
return lst;
}
void printList( TList *lst )
{
TList *pointer = lst;
printf( "\nCurrent list:\n" );
while ( pointer != NULL )
{
printf( "\tKey: %d Info: %s\n", pointer -> key, pointer -> info );
pointer = pointer -> next;
}
printf( "\n" );
}
void menu()
{
printf( "\n1) Insert data;\n" );
printf( "2) Remove data;\n" );
printf( "3) Print list;\n" );
printf( "0) Exit.\n" );
}
int main()
{
TList *list = NULL;
int choice;
do
{
menu();
printf( "\nYour choice: " );
scanf( "%d", &choice );
switch ( choice )
{
case 1 :
{
int key;
char *info = ( char* )malloc( 150 );
printf( "\n\tEnter key and info: " );
scanf( "%d%s", &key, info );
fflush( stdin );
list = backInsert( list, key, info );
} break;
case 2 :
{
int key;
printf( "\n\tEnter key for remove: " );
scanf( "%d", &key );
list = removeItem( list, key );
} break;
case 3 :
{
printList( list );
} break;
}
}
while ( choice != 0 );
return 0;
}Решение задачи: «При вводе второго ключа с информацией выводится ошибка»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Item Item;
struct Item
{
int key;
char *info;
Item *next;
};
typedef struct List List;
struct List
{
Item *head;
Item *back;
};
Item *
alloc_item(int key, char *info)
{
Item *item;
item = malloc(sizeof(Item));
if (item == NULL)
return NULL;
item->info = malloc(strlen(info)+1);
if (item->info == NULL) {
free(item);
return NULL;
}
strcpy(item->info, info);
item->key = key;
item->next = NULL;
return item;
}
void
free_item(Item *item)
{
free(item->info);
free(item);
}
int
push_back(List *list, int key, char *info)
{
Item *item;
item = alloc_item(key, info);
if (item == NULL)
return 0;
if (list->back == NULL) {
list->head = item;
list->back = item;
} else {
list->back->next = item;
list->back = item;
}
return 1;
}
void
remove_items(List *list, int key)
{
Item *item, *curr;
if (list->head->key == key) {
if (list->head->next == NULL) {
free_item(list->head);
list->head = list->back = NULL;
} else {
curr = list->head;
list->head = curr->next;
free_item(curr);
}
return;
}
for (curr = list->head; curr->next != NULL; curr = item) {
item = curr->next;
if (item->key == key) {
if (item == list->back)
list->back = curr;
curr->next = item->next;
free_item(item);
}
}
}
void
print_list(List *list, char *fmt, int newline)
{
Item *curr;
for (curr = list->head; curr != NULL; curr = curr->next)
printf(fmt, curr->key, curr->info);
if (newline)
printf("\n");
}
void
menu()
{
printf("\n");
printf("1) Insert data;\n");
printf("2) Remove data;\n");
printf("3) Print list;\n");
printf("0) Exit.\n");
printf("> ");
}
#define BUFSIZE 8192
int
main(void)
{
List list;
Item *item;
char info[BUFSIZE];
int key, choice;
list.head = list.back = NULL;
do {
menu();
scanf("%d", &choice);
switch (choice) {
case 1:
memset(info, 0, BUFSIZE);
printf("\tEnter key and info: ");
scanf("%d ", &key);
fgets(info, BUFSIZE-1, stdin);
if (!push_back(&list, key, info))
perror("can't allocate enough memory");
break;
case 2 :
printf("\tEnter key for remove: ");
scanf("%d", &key);
remove_items(&list, key);
break;
case 3:
print_list(&list, "%d. %s", 0);
break;
}
} while (choice);
while (list.head != NULL) {
item = list.head->next;
free_item(list.head);
list.head = item;
}
return 0;
}
Объяснение кода листинга программы
- Объявлены структуры данных: структура
Itemи структураList. - В структуре
Itemесть поляkey,infoиnext, а в структуреList- поляheadиback. - Функция
alloc_itemвыделяет память под новый элемент списка и заполняет его поля. - Функция
free_itemосвобождает память, выделенную под элемент списка. - Функция
push_backдобавляет новый элемент в конец списка. - Функция
remove_itemsудаляет элементы списка с заданным ключом. - Функция
print_listвыводит элементы списка на экран. - Функция
menuвыводит на экран меню программы. - В основной функции программы создается экземпляр списка, инициализированный нулевыми значениями
headиback. - В цикле программы пользователю предлагается выбрать действие из меню.
- Выбор пользователя считывается с помощью функции
scanfи переключается с помощью оператораswitch. - При выборе действия
1пользователю предлагается ввести ключ и информацию для нового элемента списка. - При выборе действия
2пользователю предлагается ввести ключ для удаления элемента списка. - При выборе действия
3на экран выводится содержимое списка. - После окончания цикла программа еще раз проходит по списку и освобождает память, выделенную под каждый элемент списка.
- Программа завершается возвратом функции
mainсо значением0.