Всем добрый вечер! Сколько писал на с/c++, но почти никогда не использовал scanf толком. Обходился форматами вроде "%d %d", а тут понадобилось - прочитал мануал, и вот какая проблема возникла: Следующий код должен в бесконечном цикле выводить приглашение "> ", запрашивать команду до символа конца строки, печатать ее и выводить следующее приглашение. Код (Text): while(1) { fprintf(output,"> "); fflush(output); int r = fscanf(input,"%31s",cmd); if (r == EOF) break; tinfo(id, cmd); /*if(!strcmp(cmd,"help")) { help(input, output); }*/ if(fscanf(input,"%*[^\n]\n")==EOF) // Игнорируем все до "\n" break; } input и output - ввод/вывод сокета, к которому подключаюсь telnet'ом. Функция tinfo печатает id и cmd (в данном случае - id=1) в stderr. Вот, что видим в telnet (жирным - ввод юзера): > qwe rty asd uio > zxc vbn > 123 456 > Вот, что имеем в stderr: Код (Text): [ 1] qwe [ 1] asd [ 1] zxc [ 1] 123 Т.е. все замечательно, кроме того, что "> " не выдается перед второй командой, а перед последующими - все ок. Пока не добавил printf("> "), даже не замечал, что что-то идет не так... В дебаггере строка "if(fscanf(input,"%*[^\n]\n")==EOF) // Игнорируем все до "\n"" блочится после ввода "qwe rty" до ввода "asd uio<enter>". Но, почему-то, "asd uio" обрабатывается и "asd" идет в stderr. Подскажите, пожалуйста, в чем может быть дело? Спасибо.
SilentSnowfall они тут и ни при чем man scanf: Код (Text): An optional '*' assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required, and this specification is not included in the count of successful assignments returned by scanf() Код (Text): [ Matches a nonempty sequence of characters from the specified set of accepted characters; the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating null byte. The usual skip of leading white space is suppressed. The string is to be made up of characters in (or not in) a particular set; the set is defined by the characters between the open bracket [ character and a close bracket ] character. The set excludes those charac‐ ters if the first character after the open bracket is a circum‐ flex (^). To include a close bracket in the set, make it the first character after the open bracket or the circumflex; any other position will end the set. The hyphen character - is also special; when placed between two other characters, it adds all intervening characters to the set. To include a hyphen, make it the last character before the final close bracket. For instance, [^]0-9-] means the set "everything except close bracket, zero through nine, and hyphen". The string ends with the appearance of a character not in the (or, with a circumflex, in) set or when the field width runs out. Это всё C89
Упс. Сфейлил, однако. Век живи, век учись. Вообще, попробуй сделать так, должно работать: Код (Text): while(1) { fprintf(output,"> "); fflush(output); int r = fscanf(input,"%31s",cmd); if (r == EOF) break; tinfo(id, cmd); /*if(!strcmp(cmd,"help")) { help(input, output); }*/ if(fscanf(input,"%*[^\n]")==EOF) // Игнорируем все до "\n" break; fgetc(input); //пропускаем '\n' }
Методом проб и ошибок проблема решилась: Код (Text): if(fscanf(input,"%*[^\n]\n")==EOF) заменить на Код (Text): if(fscanf(input,"%*[^\n]")==EOF) Походу, последний \n вызывал блокировку до ввода whitespace'а (т.е. до первого символа-не-whitespace). Хотя, пост-фактум объяснения придумывать проще). Так что если есть более адекватное - highly appreciated Сорри за потраченное время...