BOOL CMFCProjectApp::InitInstance()
{
....
int ret = 0;
FILE* fp;
AllocConsole();
ret = _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
fp = _fdopen(ret, "w");
*stdout = *fp;
setvbuf(stdout, NULL, _IONBF, 0);
}
只要将上面的函数加到初始化的地方之后,就可以使用printf输出数据到console了,当然也可以使用cout输出。
程序中用到的各个函数解析:
AllocConsole Function
为主调进程分配一个新的控制台。 语法
C++
参数无返回值如果函数成功,返回值是非零值;如果函数失败,返回值是零值。 备注一个进程仅能关联一个控制台,所以该函数在主调进程已经具有控制台时将会失败。一个进程可以使用FreeConsole 函数来释放与之关联的控制台,之后它就可以调用该函数来创建一个新的控制台或使用 AttachConsole 函数来关联另一个控制台。 如果主调进程创建了一个子进程,则子进程也将继承这个新创建的控制台。 该函数为新的控制台初始化标准输入、输出、错误句柄等。标准输入句柄是一个控制台输入缓冲的句柄,标准输出和标准错误句柄则是控制台屏幕缓冲的句柄。为了获得这些句柄,可以使用 GetStdHandle 函数。 该函数主要用于GUI应用陈旭来创建一个控制台窗口。GUI应用程序初始化时时没有控制台的,而控制台应用程序则以控制台来初始化的。 要求
|
Associates a C run-time file descriptor with an existing operating-system file handle.
int _open_osfhandle ( intptr_t osfhandle, int flags );
Parameters
-
osfhandle
- Operating-system file handle. flags
- Types of operations allowed.
Return Value
If successful, _open_osfhandle returns a C run-time file descriptor. Otherwise, it returns –1.
Remarks
The _open_osfhandle function allocates a C run-time file descriptor and associates it with the operating-system file handle specified byosfhandle. The flags argument is an integer expression formed from one or more of the manifest constants defined in FCNTL.H. When two or more manifest constants are used to form the flags argument, the constants are combined with the bitwise-OR operator ( | ).
The FCNTL.H file defines the following manifest constants:
-
_O_APPEND
- Positions file pointer to end of file before every write operation. _O_RDONLY
- Opens file for reading only. _O_TEXT
- Opens file in text (translated) mode.
Requirements
Routine | Required header | Compatibility |
---|---|---|
_open_osfhandle | <io.h> | Win 98, Win Me, Win NT, Win 2000, Win XP |
For additional compatibility information, see Compatibility in the Introduction.
Libraries
All versions of the C run-time libraries.
HANDLE GetStdHandle(
DWORD nStdHandle
);
GetStdHandle()返回标准的输入、输出或错误的设备的句柄,也就是获得输入、输出/错误的屏幕缓冲区的句柄。
其参数nStdHandle的值为下面几种类型的一种:
值 含义
STD_INPUT_HANDLE 标准输入的句柄
STD_OUTPUT_HANDLE 标准输出的句柄
STD_ERROR_HANDLE 标准错误的句柄
实例程序:
实现一个彩色的Hello World!
#include <windows.h>
//GetStdHandle和SetConsoleTextAttribute在头文件windows.h中
#include <iostream>
using namespace std;
void SetColor(unsigned short ForeColor=3,unsigned short BackGroundColor=0)
//给参数默认值,使它
//可以接受0/1/2个参数
{
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE); //本例以输出为例
SetConsoleTextAttribute(hCon,ForeColor|BackGroundColor);
}
int main()
{
SetColor();
std::cout<<"Hello world!"<<endl;
SetColor(40,30);
std::cout<<"Hello world!"<<endl;
std::cout<<"Hello world!"<<endl;
return 0;
}
Linux环境下可以使用下列函数打开一个流,其函数原型如下:
#include <stdio.h>
FILE * fopen(const char * restrict pathname,
const char * restrict type);
FILE * fdopen(int filedes, const char *type);
fopen函数的第1个参数表示需要打开文件的路径,第2个参数type表示打开的方式,该值以一个字符串的形式传入,
type 字串中包含字母a的表示"追加写",即流打开以后,文件的读写位置在文件的末尾,所以成为追加写;type字串中包括字母b的表示流以二进制文件的形式打 开,其他的则表示流以文本文件的形式打开。这一点对于Linux系统来讲没有意义,因为Linux系统下的二进制文件和文本文件都是普通文件,是字节流, 内核并不区分这二者。
如果成功打开流,fopen函数返回一个FILE对象的指针,用户可以使用该指针操作这个流;如果失败则返回NULL,并且设置errno错误号。一般来讲,fopen函数是很少出错的,其原因主要有以下3种。
指定的文件路径有问题。type参数是一个非法字符串。文件的操作权限不够。
fdopen 函数用于在一个已经打开的文件描述符上打开一个流,其第1个参数表示一个已经打开的文件描述符,第2个参数type的意义和fopen函数的第2个参数一 样。只有一点不同的是,由于文件已经被打开,所以fdopen函数不会创建文件,而且也不会将文件截短为0,这一点要特别注意。这两步操作在打开该文件描 述符的时候已经完成。
Linux环境下使用fclose函数关闭一个流,其函数原型如下:
#include <stdio.h>
int fclose(FILE *fp);
fclose函数的参数是一个FILE对象的指针,它指向需要关闭的流。如果关闭成功,fclose函数返回0,失败返回EOF。这个值是一个定义在stdio.h文件中的宏,其值是-1。
下面实例演示了打开和关闭一个流。
(1)在vi编辑器中编辑该程序如下:
程序清单21-2 stream.c 打开并关闭一个流
#include <stdio.h>
#include <fcntl.h>
int main(void)
{
FILE *fp;
int fd;
if( (fp = fopen("test.txt", "r+")) == NULL){ /* 以读写方式打开流 */
perror("fail to open");
exit(1);
}
fprintf(fp, "hello world/n"); /* 向该流输出一段信息,这段信息会反馈到文件上 */
fclose(fp); /* 关闭流 */
if( (fd = open("test.txt", O_RDWR) == -1){ /* 以读写的方式打开文件 */
perror("fail to open");
exit(1);
}
if((fp = fdopen(fd, "r+") == NULL){ /* 在打开的文件上打开一个流 */
perror("fail to open stream");
exit(1);
}
fprintf("hello world again/n");
fclose(fp); /* 关闭流,文件也被关闭 */
return 0;
}