IT TIP

C에서 stdin 및 stdout 경로 변경

itqueen 2020. 12. 3. 21:34
반응형

C에서 stdin 및 stdout 경로 변경


나는 stdinand stdout(그리고 아마도 stderr내가있는 동안) 파일 핸들 을 다시 열고 싶어요 . 그래서 미래의 printf()또는 putchar()또는 puts()파일에 대한 호출 getc()은 파일에서 나올 것입니다.

1) 표준 입력 / 출력 / 오류를 영구적으로 잃고 싶지 않습니다. 나중에 프로그램에서 다시 사용할 수 있습니다.

2) 새 파일 핸들을 열지 않으려는 이유는 이러한 파일 핸들이 많이 전달되거나 전역 적으로 전달되어야하기 때문입니다.

3) 나는 어떤 사용하지 않으 open()또는 fork()어쩔 수없는 경우 또는 다른 시스템에 의존하는 기능.

그래서 기본적으로 다음과 같이 작동합니까?

stdin = fopen("newin", "r");

그리고 만약 그렇다면 어떻게 원래의 가치를 얻을 수 stdin있습니까? 에 저장하고 FILE *나중에 다시 가져와야합니까?


왜 사용 freopen()합니까? C89 사양은 다음 섹션의 미주 중 하나에 답이 있습니다 <stdio.h>.

(116)의 주된 사용 freopen기능이 표준 텍스트 스트림에 관련된 파일을 변경하는 것 ( stderr, stdinstdout), 그 식별자에 의해 반환되는 값을 수정할 lvalues 일 필요로 fopen함수가 할당 될 수있다.

freopen예를 들어 stdin = freopen("newin", "r", stdin);. 이것은 fclose(stdin); stdin = fopen("newin", "r");. 두 표현식 모두에 할당을 시도하지만 할당 stdin이 보장되지는 않습니다.

사용하는 올바른 방법 freopen은 할당을 생략하는 것입니다.freopen("newin", "r", stdin);


나는 당신이 뭔가를 찾고 있다고 생각합니다 freopen()


이것은 Tim Post의 방법의 수정 된 버전입니다. / dev / stdout 대신 / dev / tty를 사용했습니다. stdout (/ proc / self / fd / 1에 대한 링크)에서 작동하지 않는 이유를 모르겠습니다.

freopen("log.txt","w",stdout);
...
...
freopen("/dev/tty","w",stdout);

/ dev / tty를 사용하면 출력이 앱이 시작된 터미널로 리디렉션됩니다.

이 정보가 유용하기를 바랍니다.


os 함수 dup2 () 는 필요한 것을 제공해야합니다 (필요한 것을 정확히 참조하지 않는 경우).

보다 구체적으로, stdin 파일 설명자를 다른 파일 설명자에 dup2 ()하고, stdin으로 다른 작업을 수행 한 다음 원할 때 다시 복사 할 수 있습니다.

dup () 함수는 열린 파일 설명자를 복제합니다. 특히, F_DUPFD 상수 명령 값을 사용하여 fcntl () 함수가 제공하는 서비스에 대한 대체 인터페이스를 제공하며 세 번째 인수는 0입니다. 복제 된 파일 설명자는 원본과 모든 잠금을 공유합니다.

성공하면 dup ()은 원본과 공통적으로 다음을 갖는 새 파일 설명자를 반환합니다.

  • 동일한 열린 파일 (또는 파이프)
  • 동일한 파일 포인터 (두 파일 설명자가 하나의 파일 포인터를 공유 함)
  • 동일한 액세스 모드 (읽기, 쓰기 또는 읽기 / 쓰기)

freopen("/my/newstdin", "r", stdin);
freopen("/my/newstdout", "w", stdout);
freopen("/my/newstderr", "w", stderr);

... do your stuff

freopen("/dev/stdin", "r", stdin);
...
...

이것은 내 둥근 못 사각형 구멍 미터의 바늘을 뾰족하게 만듭니다. 무엇을 성취하려고합니까?

편집하다:

stdin, stdout 및 stderr는 새로 생성 된 모든 프로세스에 대한 파일 설명자 0, 1 및 2임을 기억하십시오. freopen ()은 동일한 fd를 유지해야하며 새 스트림을 할당하면됩니다.

따라서 이것이 실제로 원하는 작업을 수행하는지 확인하는 좋은 방법은 다음과 같습니다.

printf("Stdout is descriptor %d\n", fileno(stdout));
freopen("/tmp/newstdout", "w", stdout);
printf("Stdout is now /tmp/newstdout and hopefully still fd %d\n",
   fileno(stdout));
freopen("/dev/stdout", "w", stdout);
printf("Now we put it back, hopefully its still fd %d\n",
   fileno(stdout));

나는 이것이 freopen ()의 예상되는 동작이라고 생각합니다. 보시다시피 여전히 세 개의 파일 설명자 (및 관련 스트림) 만 사용하고 있습니다.

셸이 리디렉션 할 항목이 없으므로 모든 셸 리디렉션이 무시됩니다. 그러나 아마도 파이프를 끊을 것입니다. 프로그램이 파이프 (FIFO, 파이프가 아님)의 블로킹 끝에서 자신을 발견하는 경우 SIGPIPE에 대한 핸들러를 설정하는 것이 좋습니다.

따라서 ./your_program --stdout /tmp/stdout.txt --stderr /tmp/stderr.txt는 freopen ()을 사용하여 쉽게 수행하고 동일한 실제 파일 설명자를 유지해야합니다. 내가 이해하지 못하는 것은 변경 한 후에 다시 넣어야하는 이유입니다. 분명히 누군가가 두 옵션 중 하나를 통과하면 프로그램이 종료 될 때까지 지속되기를 원할까요?


freopen solves the easy part. Keeping old stdin around is not hard if you haven't read anything and if you're willing to use POSIX system calls like dup or dup2. If you're started to read from it, all bets are off.

Maybe you can tell us the context in which this problem occurs?

I'd encourage you to stick to situations where you're willing to abandon old stdin and stdout and can therefore use freopen.


And in the meantime, there's a C source code library that will do all this for you, redirecting stdout or stderr. But the cool part is that it lets you assign as many callback functions as you want to the intercepted streams, allowing you then to very easily send a single message to multiple destinations, a DB, a text file, etc.

On top of that, it makes it trivial to create new streams that look and behave the same as stdout and stderr, where you can redirect these new streams to multiple locations as well.

look for U-Streams C library on *oogle.


this is the moste avalaible handly and usefull way

freopen("dir","r",stdin);

참고URL : https://stackoverflow.com/questions/584868/rerouting-stdin-and-stdout-from-c

반응형