重定位本进程的标准输出至文件(非子进程)

本文介绍了如何使用_C_GetOSFHandle函数将文件描述符转换为文件句柄,并通过实例展示了如何修改标准输出流。

环境:Win7、VC6

1、

代码:

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 #include <io.h>
 5 #include <Fcntl.h>
 6 
 7 int main()
 8 {
 9     printf("Sub01 : *stdin : %x\n", *stdin);
10     printf("Sub01 : *stdout : %x\n", *stdout);
11     printf("Sub01 : *stderr : %x\n", *stderr);
12     printf("\n");
13 
14     printf("Sub01 : GetStdHandle(STD_INPUT_HANDLE) return : %x\n", GetStdHandle(STD_INPUT_HANDLE));
15     printf("Sub01 : GetStdHandle(STD_OUTPUT_HANDLE) return : %x\n", GetStdHandle(STD_OUTPUT_HANDLE));
16     printf("Sub01 : GetStdHandle(STD_ERROR_HANDLE) return : %x\n", GetStdHandle(STD_ERROR_HANDLE));
17 
18 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
19     // 创建 文件
20 
21     HANDLE hFile = CreateFile("C:\\ZXC_20151109.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
22     if (hFile == INVALID_HANDLE_VALUE)
23     {
24         printf("Could not open file (error %d)/n", GetLastError());
25         return 0;
26     }
27 
28     // 从句柄,得到 文件描述符(File Description)
29     int fd = _open_osfhandle((long)hFile, _O_TEXT);
30     // 由 fd 创建流
31     FILE* fp = _fdopen( fd, "w+" );
32     // 更改 标准输出流
33     *stdout = *fp;
34 
35     printf("Sub01 : *stdin : %x\n", *stdin);
36     printf("Sub01 : *stdout : %x\n", *stdout);
37     printf("Sub01 : *stderr : %x\n", *stderr);
38     printf("\n");
39 
40     printf("Sub01 : GetStdHandle(STD_INPUT_HANDLE) return : %x\n", GetStdHandle(STD_INPUT_HANDLE));
41     printf("Sub01 : GetStdHandle(STD_OUTPUT_HANDLE) return : %x\n", GetStdHandle(STD_OUTPUT_HANDLE));
42     printf("Sub01 : GetStdHandle(STD_ERROR_HANDLE) return : %x\n", GetStdHandle(STD_ERROR_HANDLE));
43 
44     return 0;
45 }

 

控制台输出:

1 Sub01 : *stdin : 428600
2 Sub01 : *stdout : 0
3 Sub01 : *stderr : 0
4 
5 Sub01 : GetStdHandle(STD_INPUT_HANDLE) return : 3
6 Sub01 : GetStdHandle(STD_OUTPUT_HANDLE) return : 7
7 Sub01 : GetStdHandle(STD_ERROR_HANDLE) return : b
8 Press any key to continue

 

文件ZXC_20151109.txt中的输出:

1 Sub01 : *stdin : 428600
2 Sub01 : *stdout : 293d20
3 Sub01 : *stderr : 0
4 
5 Sub01 : GetStdHandle(STD_INPUT_HANDLE) return : 3
6 Sub01 : GetStdHandle(STD_OUTPUT_HANDLE) return : 7
7 Sub01 : GetStdHandle(STD_ERROR_HANDLE) return : b

 

 

 

PS:由 文件描述符(fd:File Description) 得到 对应的文件句柄(file handle)(HANDLE) : “long = _get_osfhandle(int fd);”。

PS:网页资料:(http://demon.tw/programming/_get_osfhandle.html)

_get_osfhandle函数可以获取文件描述符(file descriptor)对应的文件句柄(file handle)。

众所周知,系统中stdin、stdout、stderr的文件描述符分别是0、1、2,所以可以用_get_osfhandle函数来获取它们的句柄。

#include <io.h>
#include <tchar.h>
#include <windows.h>

int main()
{
    LPTSTR s = TEXT("http://demon.tw\n");
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    HANDLE _hStdOut = (HANDLE) _get_osfhandle(1);
    if (hStdOut == _hStdOut) {
        WriteConsole(hStdOut, s, lstrlen(s), NULL, NULL);
    }
    return 0;
}

可以看到,_get_osfhandle的返回值和GetStdHandle取得的标准输出句柄是一样的。

我的测试代码:

 1 #include <windows.h>
 2 #include <stdio.h>
 3 
 4 #include <io.h>
 5 #include <Fcntl.h>
 6 
 7 int main()
 8 {
 9     char* s = "http://demon.tw\n";
10     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
11     HANDLE _hStdOut = (HANDLE) _get_osfhandle(1);
12     if (hStdOut == _hStdOut) {
13         WriteConsole(hStdOut, s, lstrlen(s), NULL, NULL);
14     }
15 
16     printf("_hStdOut : %x , GetStdHandle(STD_OUTPUT_HANDLE) : %x\n", _hStdOut, hStdOut);
17     return 0;
18 }

控制台的输出:

http://demon.tw
_hStdOut : 7 , GetStdHandle(STD_OUTPUT_HANDLE) : 7
Press any key to continue

 

 

 

Z

 

转载于:https://www.cnblogs.com/CodeSkill/p/4949877.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值