fgetc, switch в switch

Есть цикл

struct char_list *list, *sub = NULL;
while((c = fgetc(stdin)) != EOF){
    switch(c){
        case 0x31:
            struct char_list *tmp;
            char *str = "Vvedite (# - exit):\n";
            int d;
            fputs(str, stdout);
            d = fgetc(stdin) /* 1 */
            while((d = fgetc(stdin)) != EOF){
                switch(d){
                    case '\n':
                    case '#':
                        break;
                    default:
                        tmp = malloc(sizeof(*tmp));
                        tmp->char = d;
                        tmp->next = NULL;
                        if(sub){
                            sub->next = tmp;
                            sub = sub->next;
                        } else
                            list = sub = tmp;
                }
                if(d == '\n' || d == '#')
                    break; /*список для 1 строки готов*/
            }
            if(d != '#'){
                char *str1 = char_list_to_str(list) /* строка 1 готова */;
                free_list(list) /*Функция чистит список*/
                printf("str1: ['%s']", str1); /*тут все норм и печатает и никаких ошибок*/
                sub = NULL;
                puts("Vvedite 2:");
                while((b = fgetc(stdin)) != EOF){
                    switch(d){
                        case '\n':
                        case '#':
                            break;
                        default:
                            tmp = malloc(sizeof(*tmp));
                            tmp->char = d;
                            tmp->next = NULL;
                            if(sub){
                                sub->next = tmp;
                                sub = sub->next;
                            } else
                                list = sub = tmp;
                    }
                    if(b == '\n' || b == '#')
                        break; /*строка 2 готова*/
                }
                if(b != '#'){
                    char *str1 = char_list_to_str(list); /* А тут segmentation fault(core dumped)...*/
                    free_list(list);
                }
            } else{
                if(list)
                    free_list(list);
            }
            break;
    }
}

Вот есть цикл, в нем есть свитч в внутри этого свитча еще один свитч, во первых, правильно ли так реализовывать (типа меню, в начале программы выдается строка с цифрами, цифры - пункт меню, один из пунктов строит список из букв, а потом делает строку маллоком, потом чистит этот список и снова делает так же вторую строку с помощью того же указателя на список) как-то можно по-другому и лучше? Не важно почему 0х31 ('1'), не важно почему *str = "Vvedite:\n" и тд, код показывает конструкцию в целом, вопросы:

/* 1 */ комментарий - как мне сделать так, что бы ввод пошел с самого начала и выведенная строка для этого цикла нового d = fgetc(stdin) никак не влияла? Я поставил перед циклом d = fgetc(stdin), но не совсем понимаю что происходит, а это работает, так же не совсем понимаю как работает fflush и scanf("%*[^\n]")... Такая же проблема, если я введу asd#52345, то после # основной switch выполнит 5, потом 2 и тд, то есть в основной цилк попадет 52345. Как от этого избавиться?

И второй вопрос: там где segmentation fault, почему может быть, вроде очистил указатели...

Фнукция free_list выглядит так:

void free_list(struct char_list *list)
{
    while(list){
        struct char_list *tmp = list;
        list = list->next;
        free(tmp);
    }
}

Вообще программа будет делать типа ассоциативный массив с помощью красно-черного дерева, case 0x31 должен добавляьб в дерево пару ключ - значение(но чет пока не получается 2 слова получить).


Ответы (1 шт):

Автор решения: nx4n

/* 1 */ - на самом деле новый цикл внутри case с участием fgetc брал в себя символы из предыдущей строки, которую я вводил для основного цикла, то есть ввел 1, нажал enter, case 0x31 сработал и '\n' заносился в d = fgetc... Не знаю что лучше тут делать, fflush(stdin) не помог, единственное решение для себя нашел - это при входе в case писать строку while(fgetc(stdin) != '\n'); и все...

Segmentation fault - в функции был нюанс, для подсчета символов в списке я зачем-то внутри функции определил статическую переменную. Может рекурсию хотел сделать сперва, а потом забыл убрать...

→ Ссылка