zoukankan      html  css  js  c++  java
  • 重定位本进程的标准输出至文件(非子进程)

    环境: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

  • 相关阅读:
    SDWebImage内存性能优化
    dataGridView1数据导出
    listView数据导出
    sqlserver定时备份
    C#-IniFiles文件配置连接数据库
    (转)线程同步详解
    C#工具类:Json操作帮助类(转载)
    c#实现验证码功能
    屏蔽F12审查元素,禁止使用右键菜单
    c# excel如何导入到sqlserver数据库
  • 原文地址:https://www.cnblogs.com/CodeSkill/p/4949877.html
Copyright © 2011-2022 走看看