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