2012-06-26 4 views
2

C 언어가 사용됩니다. stdout에 쓰는 함수가 있습니다.stdout을 문자열로 캡쳐 한 후 C 언어의 stdout으로 다시 출력하십시오.

출력을 캡처하고 약간 수정하십시오 (일부 문자열 대체). 그리고 표준 출력으로 다시 출력하십시오. 어떻게 원래의 stdout으로 다시 I 출력 huge_string_buffer을 수행

char huge_string_buf[MASSIVE_SIZE]; 
freopen("NUL", "a", stdout); -OR- freopen("/dev/null", "a", stdout); 
setbuf(stdout, huge_string_buffer); 
/* modify huge_string_buffer */ 

문제는 지금 : 그래서 시작하고 싶어?

답변

0

저는 파일 설명자가있는 까다로운 게임을 정말로 좋아하지 않습니다. stdout에 쓰는 것보다 다른 방법으로 데이터를 반환하도록 함수를 수정할 수 없습니까?

소스 코드에 액세스 할 수 없으며 그렇게 할 수 없다면 stdout에 작은 코드로 쓴 코드를 작성하고 다른 프로세스로 실행하는 것이 좋습니다. 프로세스에서 출력을 리다이렉트하는 것이 쉽고 깨끗하다. (아마도 named pipe를 통해), 데이터를받는 프로세스에서 stdout으로 출력하는 데 아무런 문제가 없을 것이다.

또한 편집하려는 종류에 따라 파이썬과 같은 고급 언어를 사용하여 데이터를 편집하는 것이 좋습니다.

+0

글쎄, 이미 파이썬으로 끝났지 만 ANSI C로 다시 통합해야합니다. 그래서 다른 프로세스를 호출하는 것 외에는 다른 방법이 없습니까? 스택 높이를 어딘가에 위반하지 않아도되는지 잘 모르겠습니다. – Stasik

+0

C를 사용하는 데 제약이되는 것은 무엇입니까? 좀 더 깔끔한 접근법은 필요한 변경을 수행하는 것보다 (프로그램 라인 사용, OS가 파이프를 지원한다고 가정 할 때) 필터를 통해 프로그램의 출력을 파이프하는 것입니다. – Throwback1986

+1

constrains는 마이크로 컨트롤러의 기존 빌드 및 릴리스 시스템 + 런타임입니다. – Stasik

0

파이썬은 여러분이 원하는 것을 성취하기위한 훌륭한 방법을 가지고 있습니다. 그러나 C 언어를 사용해야 할 필요가 있다면 C 언어로 파이프를 읽는 것이 좋을 것입니다.

1

유닉스는 실제로 필요한 입력 처리를 수행하는 작은 프로그램을 작성한 다음 다른 프로그램의 출력을 명령 행에서 파이프 처리합니다.

당신이 C 프로그램에서 모든 것을 지키고 자한다면, 내가 대신 할 일은 주어진 char 버퍼 (바람직하게는 return ing the buffer의 char *)에 출력을 보내도록 함수를 다시 작성하는 것입니다. stdout으로 보내거나 클라이언트가 원하는대로 처리 할 수 ​​있습니다.

예를 들면, 옛날 방식 :

void usage() { 
    printf ("usage: frob sourcefile [-options]\n"); 
} 

... 그리고 새로운 방법 :

char * usage(char * buffer) { 
    strcpy (buffer, "usage: frob sourcefile [-options]\n"); 
    return buffer; 
} 
+1

funciton 소스가 없습니다. 이것은 .so – Stasik

+0

에서 호출됩니다. @Stasik 솔루션을 가지고 있습니까? 나는 같은 문제가있다. ipmitool을 실행하여 정보를 얻고 내용을 수정하여 표준 출력으로 출력하려고한다. ipmitool 코드가 있지만 코드를 너무 많이 변경하고 싶지 않습니다. –

+1

스크립트로 마무리하고 텍스트 처리를 끝냈습니다. – Stasik

0
char huge_string_buf[MASSIVE_SIZE]; 
FILE stdout_ori=fdopen(stdout,"a"); 
freopen("NUL", "a", stdout); -OR- freopen("/dev/null", "a", stdout); 
setbuf(stdout, huge_string_buffer); 
/* modify huge_string_buffer */ 
//Write to stdout_fdopen 
+1

fdopen stdout가 작동하지 않습니다. ( – Stasik

2

하나의 아이디어는 표준 유닉스 유틸리티 tee의 기능을 모방하는 것입니다, 외부 리디렉션에 의존하지 않고 프로그램 내에서 그렇게 할 수 있습니다.

간단한 함수 mytee()을 작성 했으므로 효과가있는 것 같습니다. 그것은 shmget(), pipe(), fork(), and dup2() 사용

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/shm.h> 

static char *mytee(int size) { 
    int shmid = shmget(IPC_PRIVATE, size + 1, 0660 | IPC_CREAT); 
    int pipe_fds[2]; 
    pipe(pipe_fds); 

    switch (fork()) { 
     case -1:      // = error 
     perror("fork"); 
     exit(EXIT_FAILURE); 
     case 0: {      // = child 
     char *out = shmat(shmid, 0, 0), c; 
     int i = 0; 
     out[0] = 0; 
     dup2(pipe_fds[0], 0);  // redirect pipe to child's stdin 
     setvbuf(stdout, 0, _IONBF, 0); 
     while (read(0, &c, 1) == 1 && i < size) { 
      printf("<%c>", c);  // pass parent's stdout to real stdout, 
      out[i++] = c;   // and then buffer in mycapture buffer 
      out[i] = 0;    // (the extra <> are just for clarity) 
     } 
     _exit(EXIT_SUCCESS); 
     } 
     default:      // = parent 
     dup2(pipe_fds[1], 1);  // replace stdout with output to child 
     setvbuf(stdout, 0, _IONBF, 0); 
     return shmat(shmid, 0, 0); // return the child's capture buffer 
    } 
} 

내 테스트 프로그램은 다음과 같습니다

int main(void) { 
    char *mycapture = mytee(100); // capture first 100 bytes 
    printf("Hello World");   // sample test string 
    sleep(1); 
    fprintf(stderr, "\nCaptured: <%s>\n", mycapture); 
    return 0; 
} 

출력은 다음과 같습니다

<H><e><l><l><o>< ><W><o><r><l><d> 
Captured: <Hello World> 

응용 프로그램에서이를 사용하려면 mytee()에서 당신은거야 테스트 문 printf("<%c>", c)을 (를)(으)로 대체해야합니다..read으로 전화를 걸면 신호를 처리해야 할 수도 있습니다. 물건의 종류에 참고

close(pipe_fds[0]); 
    close(pipe_fds[1]); 

우수한 짧은 27 세 220 페이지 오라일리 예를 들어, 참조 : 그리고 두 dup2() 년대의 각 후, 당신은 추가 할 수 있습니다 bookDave Curry의 Unix 시스템에서 C 사용.

관련 문제