Полагаю, у вас все хорошо, за исключением того, что проверка типов просто делает фильтрованный тип не отличным от возвращаемого типа.
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = array.filter(f => f !== undefined && f !== null) as any;
console.log(filterdArray);
Мне нравится идея использовать freopen
. Вы также можете перенаправить stdout
в канал, используя dup и dup2 , а затем использовать read
для получения данных из канала. .
Примерно так:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_LEN 40
int main( int argc, char *argv[] ) {
char buffer[MAX_LEN+1] = {0};
int out_pipe[2];
int saved_stdout;
saved_stdout = dup(STDOUT_FILENO); /* save stdout for display later */
if( pipe(out_pipe) != 0 ) { /* make a pipe */
exit(1);
}
dup2(out_pipe[1], STDOUT_FILENO); /* redirect stdout to the pipe */
close(out_pipe[1]);
/* anything sent to printf should now go down the pipe */
printf("ceci n'est pas une pipe");
fflush(stdout);
read(out_pipe[0], buffer, MAX_LEN); /* read from pipe into buffer */
dup2(saved_stdout, STDOUT_FILENO); /* reconnect stdout for testing */
printf("read: %s\n", buffer);
return 0;
}
Если вы работаете с GNU libc, вы можете использовать потоки памяти .
Почему бы вам не обернуть все свое приложение другим? По сути, вам нужна умная кошка
, которая копирует stdin в stdout, при необходимости буферизуя. Затем используйте стандартное перенаправление stdin / stdout. Это можно сделать вообще без изменения вашего текущего приложения.
~MSalters/# YourCurrentApp | bufcat
Вы можете «перенаправить» stdout
в файл с помощью freopen ()
.
man freopen
говорит:
Функция freopen () открывает файл чье имя - строка, на которую указывает по пути и связывает поток указал на поток с ним. В исходный поток (если он существует) закрыто. Используется аргумент режима точно так же, как в функции fopen (). Основное использование freopen () функция - изменить файл связанный со стандартным текстом поток (stderr, stdin или stdout).
Этот файл вполне может быть конвейером - потоки будут писать в этот конвейер, а поток записи будет слушать.
Вы можете изменить способ работы буферизации с помощью setvbuf ()
или setbuf ()
. Здесь есть описание: http://publications.gbdirect.co.uk/c_book/chapter9/input_and_output.html .
[Edit]
stdout
на самом деле является ФАЙЛОМ *
. Если существующий код работает с FILE *
s, я не вижу, что мешает ему работать с stdout
.
Одним из решений (для обеих вещей, которые вы делаете) было бы использование собирающей записи через writev .
Каждый поток мог бы, например, sprintf в буфер iovec, а затем передать указатели iovec в поток записи и попросить его просто вызвать writev с помощью stdout.
Вот пример использования writev из Расширенное программирование Unix
В Windows вы можете использовать WSAsend для аналогичных функций.
Метод, использующий 4096 bigbuf, работает только в некоторой степени. Я пробовал этот код, и хотя он успешно записывает стандартный вывод в буфер, он непригоден для использования в реальных условиях. У вас нет возможности узнать, какова длина захваченного вывода, поэтому невозможно узнать, когда завершить строку '\ 0'. Если вы попытаетесь использовать буфер, вы получите 4000 символов мусора, если вы успешно захватили 96 символов вывода stdout.
В моем приложении я использую интерпретатор perl в программе на языке C. Я понятия не имею, сколько вывода будет выплевываться из того, какой документ будет брошен в программу C, и, следовательно, приведенный выше код никогда не позволил бы мне чисто распечатать этот вывод где-либо.