2016-09-06 4 views
0

Я пытаюсь отключить функцию вывода вывода. Функция передает данные в stdout, поэтому моя идея состояла в том, чтобы получить контроль над буфером stdout и проверить, правильно ли функция правильно записывает правильные данные в буфер.Управление буфером для stdout

setvbuf показалось мне идеальным для достижения этой цели.

Я использовал setvbuf для перенаправления stdout для использования моего собственного указанного буфера.

Я использовал режим потоковой передачи _IOFBF, так что теоретически внутренний флеш происходит только в том случае, если буфер заполнен. BUFSIZ в моей системе имеет размер 8192 байта ... что более чем достаточно для выхода тестируемой функции без внутренней очистки во время вызова.

Мой источник в настоящее время выглядит следующим образом:

char buffer [BUFSIZ] = {0}; 

/* any outputs before redirecting */ 
printf("0\n"); 

/* output any remaining data */ 
fflush(stdout); 
/* redirect to my buffer with full buffering */ 
setvbuf(stdout,buffer,_IOFBF,BUFSIZ); 

/* testcode ... output of the function under test */ 
printf("1\n"); 
printf("2\n"); 

/* output any remaining data */ 
fflush(stdout); 
/* restore internal buffering with line buffering */ 
setvbuf(stdout,NULL,_IOLBF,BUFSIZ); 

/* let us see what is in our buffer */ 
printf("%s",buffer); 

Отладка этот код показывает, что "2 \ п" переписывает "1 \ П" в буфере во время секции testcode (GCC 5.4.0 x64 GNU Libc версии: 2,23)

Выход:

0 
1 
2 
2 

Но я ожидал:

0 
1 
2 
1 
2 

Я буду признателен за любые намеки.

+0

Я не могу воспроизвести ошибку ; Я получаю ожидаемый результат. – Beta

+0

Благодарим за проверку. Не уверен теперь, если это ошибка в обработке клип-буфера в моей системе. Какой компилятор + версия вы использовали для проверки? – marcas756

+0

Возможно, слишком поздно использовать 'setvbuf()'? C11dr 7.21.5.6 2 "Функция setvbuf может использоваться только после того, как поток, на который указывает поток, был связан с открытым файлом ** и перед любой другой операцией ** (кроме неудачного вызова setvbuf) выполняется в потоке «. – chux

ответ

0

После того, как вы столкнулись с закрытием и открытием stdout, «dup» -ing, запись в файл и чтение из файла и другие странные решения, я нашел тот, который соответствует моим потребностям, но не является переносимым, но не нуждается в другом файле должен быть открыт:

How to buffer stdout in memory and write it from a dedicated thread

#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; 
} 

После перезаписи его, чтобы сделать свой собственный модуль "stdout_redirect.c" это приводит:

#define BIGENOUGH 1000 
#define PIPE_READ 0 
#define PIPE_WRITE 1 

char stdout_buffer [BIGENOUGH]; 
static int stdout_save; 
static int stdout_pipe[2]; 

bool stdout_redirect() 
{ 
    stdout_save = dup(STDOUT_FILENO); /* save stdout for display later */ 

    if(pipe(stdout_pipe) != 0) {   /* make a pipe */ 
     return false; 
    } 

    dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO); /* redirect stdout to the pipe */ 
    close(stdout_pipe[PIPE_WRITE]); 

    return true; 
} 

ssize_t stdout_restore() 
{ 
    ssize_t size; 
    fflush(stdout); /* flush if not flushed before */ 
    size = read(stdout_pipe[PIPE_READ], stdout_buffer, sizeof(stdout_buffer)); /* read from pipe into buffer */ 
    close(stdout_pipe[PIPE_READ]); 
    dup2(stdout_save, STDOUT_FILENO); /* reconnect stdout */ 
    return size; 
} 
Смежные вопросы