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

环境: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
", *stdin);
10     printf("Sub01 : *stdout : %x
", *stdout);
11     printf("Sub01 : *stderr : %x
", *stderr);
12     printf("
");
13 
14     printf("Sub01 : GetStdHandle(STD_INPUT_HANDLE) return : %x
", GetStdHandle(STD_INPUT_HANDLE));
15     printf("Sub01 : GetStdHandle(STD_OUTPUT_HANDLE) return : %x
", GetStdHandle(STD_OUTPUT_HANDLE));
16     printf("Sub01 : GetStdHandle(STD_ERROR_HANDLE) return : %x
", 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
", *stdin);
36     printf("Sub01 : *stdout : %x
", *stdout);
37     printf("Sub01 : *stderr : %x
", *stderr);
38     printf("
");
39 
40     printf("Sub01 : GetStdHandle(STD_INPUT_HANDLE) return : %x
", GetStdHandle(STD_INPUT_HANDLE));
41     printf("Sub01 : GetStdHandle(STD_OUTPUT_HANDLE) return : %x
", GetStdHandle(STD_OUTPUT_HANDLE));
42     printf("Sub01 : GetStdHandle(STD_ERROR_HANDLE) return : %x
", 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
");
    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
";
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
", _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