scanf? printf? sockets?

Тема в разделе "LANGS.C", создана пользователем triumhiz, 9 фев 2011.

  1. triumhiz

    triumhiz New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2011
    Сообщения:
    5
    Всем добрый вечер!

    Сколько писал на с/c++, но почти никогда не использовал scanf толком. Обходился форматами вроде "%d %d", а тут понадобилось - прочитал мануал, и вот какая проблема возникла:

    Следующий код должен в бесконечном цикле выводить приглашение "> ", запрашивать команду до символа конца строки, печатать ее и выводить следующее приглашение.
    Код (Text):
    1.     while(1) {
    2.         fprintf(output,"> ");
    3.         fflush(output);
    4.         int r = fscanf(input,"%31s",cmd);
    5.         if (r == EOF)
    6.             break;
    7.         tinfo(id, cmd);
    8.         /*if(!strcmp(cmd,"help")) {
    9.             help(input, output);
    10.         }*/
    11.         if(fscanf(input,"%*[^\n]\n")==EOF) // Игнорируем все до "\n"
    12.             break;
    13.     }
    input и output - ввод/вывод сокета, к которому подключаюсь telnet'ом.
    Функция tinfo печатает id и cmd (в данном случае - id=1) в stderr.

    Вот, что видим в telnet (жирным - ввод юзера):
    > qwe rty
    asd uio
    > zxc vbn
    > 123 456
    >

    Вот, что имеем в stderr:
    Код (Text):
    1. [  1] qwe
    2. [  1] asd
    3. [  1] zxc
    4. [  1] 123
    Т.е. все замечательно, кроме того, что "> " не выдается перед второй командой, а перед последующими - все ок.
    Пока не добавил printf("> "), даже не замечал, что что-то идет не так...

    В дебаггере строка "if(fscanf(input,"%*[^\n]\n")==EOF) // Игнорируем все до "\n"" блочится после ввода "qwe rty" до ввода "asd uio<enter>". Но, почему-то, "asd uio" обрабатывается и "asd" идет в stderr.

    Подскажите, пожалуйста, в чем может быть дело?

    Спасибо.
     
  2. SilentSnowfall

    SilentSnowfall New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2011
    Сообщения:
    27
    *[^\n] - WTF? oO
    Семейство printf-like функций вообще-то не поддерживает регулярные выражения.
     
  3. triumhiz

    triumhiz New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2011
    Сообщения:
    5
    SilentSnowfall
    они тут и ни при чем
    man scanf:
    Код (Text):
    1. An  optional '*' assignment-suppression character: scanf() reads
    2.               input as directed by the conversion specification, but  discards
    3.               the  input.   No corresponding pointer argument is required, and
    4.               this specification is not included in the  count  of  successful
    5.               assignments returned by scanf()
    Код (Text):
    1. [      Matches a nonempty sequence of characters from the specified set
    2.               of  accepted  characters;  the next pointer must be a pointer to
    3.               char, and there must be enough room for all  the  characters  in
    4.               the  string,  plus  a  terminating null byte.  The usual skip of
    5.               leading white space is suppressed.  The string is to be made  up
    6.               of  characters  in  (or  not  in)  a  particular set; the set is
    7.               defined by the characters between the open bracket  [  character
    8.               and a close bracket ] character.  The set excludes those charac‐
    9.               ters if the first character after the open bracket is a  circum‐
    10.               flex  (^).   To  include a close bracket in the set, make it the
    11.               first character after the open bracket or  the  circumflex;  any
    12.               other position will end the set.  The hyphen character - is also
    13.               special; when placed between two other characters, it  adds  all
    14.               intervening characters to the set.  To include a hyphen, make it
    15.               the  last  character  before  the  final  close  bracket.    For
    16.               instance,  [^]0-9-]  means  the  set  "everything  except  close
    17.               bracket, zero through nine, and hyphen".  The string  ends  with
    18.               the appearance of a character not in the (or, with a circumflex,
    19.               in) set or when the field width runs out.
    Это всё C89
     
  4. SilentSnowfall

    SilentSnowfall New Member

    Публикаций:
    0
    Регистрация:
    8 фев 2011
    Сообщения:
    27
    Упс. Сфейлил, однако. Век живи, век учись.

    Вообще, попробуй сделать так, должно работать:

    Код (Text):
    1. while(1) {
    2.         fprintf(output,"> ");
    3.         fflush(output);
    4.         int r = fscanf(input,"%31s",cmd);
    5.         if (r == EOF)
    6.             break;
    7.         tinfo(id, cmd);
    8.         /*if(!strcmp(cmd,"help")) {
    9.             help(input, output);
    10.         }*/
    11.         if(fscanf(input,"%*[^\n]")==EOF) // Игнорируем все до "\n"
    12.             break;
    13.         fgetc(input); //пропускаем '\n'
    14.     }
     
  5. triumhiz

    triumhiz New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2011
    Сообщения:
    5
    Методом проб и ошибок проблема решилась:
    Код (Text):
    1. if(fscanf(input,"%*[^\n]\n")==EOF)
    заменить на
    Код (Text):
    1. if(fscanf(input,"%*[^\n]")==EOF)
    Походу, последний \n вызывал блокировку до ввода whitespace'а (т.е. до первого символа-не-whitespace).

    Хотя, пост-фактум объяснения придумывать проще). Так что если есть более адекватное - highly appreciated
    Сорри за потраченное время...
     
  6. triumhiz

    triumhiz New Member

    Публикаций:
    0
    Регистрация:
    9 фев 2011
    Сообщения:
    5
    Эм...
    SilentSnowfall, спасибо)
    Мне мораль - чаще нажимать F5