чтение из STDIN, Chicken Scheme

Я знаю, как (более или менее) сделать это в C:

#include <stdio.h>
#include <string.h>

int
main(int argc, char** argv)
{
  char buf[BUFSIZ];
  fgets(buf, sizeof buf, stdin); // reads STDIN into buffer `buf` line by line
  if (buf[strlen(buf) - 1] == '\n')
  {
    printf("%s", buf);
  }
  return 0;
}

Желаемым конечным результатом является чтение STDIN из канала, если он присутствует. (Я знаю, что приведенный выше код этого не делает, но я не мог понять, как сделать это только при чтении из канала/heredoc).

Как мне сделать что-то подобное в схеме Chicken?

Как я уже говорил, конечная цель состоит в том, чтобы иметь возможность сделать это:

echo 'a' | ./read-stdin
# a

./read-stdin << EOF
a
EOF
# a

./read-stdin <<< "a"
 # a

./read-stdin <(echo "a")
 # a

./read-stdin < <(echo "a")
 # a

person Alexej Magura    schedule 20.03.2014    source источник
comment
Как только сработает любой из первых трех, сработают и остальные два. Четвертый предоставляет имя файла в командной строке, который программа read-stdin должна открыть и прочитать. Возможно, вы хотели написать: ./read-stdin < <(echo "a") который перенаправляет на стандартный ввод; затем, как только один работает, они все работают.   -  person Jonathan Leffler    schedule 20.03.2014
comment
@JonathanLeffler, какое это имеет отношение к чему-либо? Примеры zsh с read-stdin — это просто примеры. В zsh и cat < <(echo a), и cat <(echo a) дают одинаковый результат. На самом деле у меня нет программы read-stdin, которая действительно делает вышеперечисленное, я просто пытался проиллюстрировать, каким должен быть конечный результат.   -  person Alexej Magura    schedule 20.03.2014
comment
Между cat < <(echo a) и cat <(echo a) есть разница; в первом оболочка открывает файл, а во втором cat делает. Итак, последний пример требует действий от вашей предполагаемой read-stdin программы, отличных от других примеров. Кроме этого, боюсь, это не продвинет вас к ответу. Я бы помог, если бы знал что-нибудь о Chicken Scheme, но я никогда не слышал об этом до вашего вопроса, и я достаточно мало знаю о Scheme (но я как бы использовал его для вещей чуть более сложных, чем «привет, мир»).   -  person Jonathan Leffler    schedule 20.03.2014


Ответы (1)


Догадаться.

;; read-stdin.scm

(use posix)
;; let me know if STDIN is coming from a terminal or a pipe/file
(if (terminal-port? (current-input-port))
   (fprintf (current-error-port) "~A~%" "stdin is a terminal") ;; prints to stderr
   (fprintf (current-error-port) "~A~%" "stdin is a pipe or file"))
;; read from STDIN
(do ((c (read-char) (read-char)))
   ((eof-object? c))
   (printf "~C" c))
(newline)

Согласно Курице вики, terminal-port? в языке Chicken эквивалентен функции isatty() языка C.

ПРИМЕЧАНИЕ

Приведенный выше пример работает лучше при компиляции. Запуск его с csi, кажется, заставляет terminal-port? всегда возвращать true, но, возможно, добавление явного вызова (exit) и th-го конца файла приведет к выходу из интерпретатора Chicken Scheme, что позволит STDIN быть чем-то другим, кроме терминала?

person Alexej Magura    schedule 23.03.2014