cc++console(控制台)编程详解
前⾔:
控制台⽂本窗⼝的控制是基于win32 api(win32 api可理解为微软给我们提供的⼀系列函数的集合)实现的;
例1:
#include <stdio.h>int main()
{
printf("Hello World!\n");
return0;
}
运⾏结果:
例1中,我们⽤printf()函数实现在控制台输出了hello world!然⽽当我们想要将之前输出的内容清除时,在stdio.h中的函数并不能满⾜我们的需求;这时我们就要借助于win32 api函数
例2:
#include <stdio.h>
#include <windows.h>
int main()
{
printf("Hello World!\n");
Sleep(1000);
system("cls");
return0;
}
运⾏结果:
例2中,⽤到windows.h中的Sleep();system();函数,Sleep(1000)函数功能为延时1s后程序向下运⾏,system(“cls”)清除内容,所以在例2中,程序运⾏显⽰hello world!⼀秒后就清除
⽤于控制台窗⼝操作的API函数如下:
GetConsoleScreenBufferInfo 获取控制台窗⼝信息
GetConsoleTitle 获取控制台窗⼝标题
ScrollConsoleScreenBuffer 在缓冲区中移动数据块
SetConsoleScreenBufferSize 更改指定缓冲区⼤⼩
SetConsoleTitle 设置控制台窗⼝标题
SetConsoleWindowInfo 设置控制台窗⼝信息
例3:
#include <windows.h>
#include <stdio.h>
int main(void)
{
SetConsoleTitle(L"hello world!"); // 设置窗⼝标题
printf("hello world!");
return0;
}
运⾏结果:
在例3中,我们使⽤了setconsoletitle()函数;窗⼝标题已然改变成为hello world!了
关于其它函数的使⽤⽅法,可以度,这⾥暂且不做赘述了。。。。。
1.控制台初始化
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
//设置控制台窗⼝标题
//SetConsoleTitle("更改标题字符串")
SetConsoleTitleA("hello world!");
//获取控制台窗⼝信息;
//GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, CONSOLE_SCREEN_BUFFER_INFO *bInfo)    //第⼀个hConsoleOutput参数(标准控制句柄)通过GetStdHandle()函数返回值获得
//第⼆个参数CONSOLE_SCREEN_BUFFER_INFO 保存控制台信息结构体指针
/*数据成员如下:
{
COORD dwSize; // 缓冲区⼤⼩
COORD dwCursorPosition; //当前光标位置
WORD wAttributes; //字符属性
SMALL_RECT srWindow; //当前窗⼝显⽰的⼤⼩和位置
COORD dwMaximumWindowSize; //最⼤的窗⼝缓冲区⼤⼩
}
*/
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo(hOutput, &bInfo);
cout << "窗⼝缓冲区⼤⼩:" << bInfo.dwSize.X << ", " << bInfo.dwSize.Y << endl;
cout << "窗⼝坐标位置:" << bInfo.srWindow.Left << ", " << bInfo.srWindow.Top
<< ", "<< bInfo.srWindow.Right << ", " << bInfo.srWindow.Bottom << endl;
//设置显⽰区域坐标
//SetConsoleWindowInfo(HANDLE, BOOL, SMALL_RECT *);
SMALL_RECT rc = {0,0, 79, 24}; // 坐标位置结构体初始化
SetConsoleWindowInfo(hOutput,true ,&rc);
cout << "窗⼝显⽰坐标位置:" << bInfo.srWindow.Left << ", " << bInfo.srWindow.Top
<< ", "<< bInfo.srWindow.Right << ", " << bInfo.srWindow.Bottom << endl;
//更改指定缓冲区⼤⼩
//SetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize)
/
/COORD为⼀个数据结构体
COORD dSiz = {80, 25};
SetConsoleScreenBufferSize(hOutput, dSiz);
cout << "改变后⼤⼩:" << dSiz.X << ", " << dSiz.Y << endl;
//获取控制台窗⼝标题
//GetConsoleTitle(LPTSTR lpConsoleTitle, DWORD nSize)
//lpConsoleTitle为指向⼀个缓冲区指针以接收包含标题的字符串;nSize由lpConsoleTitle指向的缓冲区⼤⼩char cTitle[255];
GetConsoleTitleA(cTitle, 255);
cout << "窗⼝标题:" << cTitle << endl;
// 关闭标准输出设备句柄
CloseHandle(hOut);
return0;
}
运⾏结果:
2.设置⽂本属性(⽂本颜⾊、移动控制)
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
/*设置⽂本属
BOOL SetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttributes);//句柄, ⽂本属性*/
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄
WORD wr1 = 0xfa;//定义颜⾊属性;第⼀位为背景⾊,第⼆位为前景⾊
SetConsoleTextAttribute(hOut, wr1);
cout << "hello world!" << endl;
printf怎么加endlWORD wr2 = FOREGROUND_RED | FOREGROUND_INTENSITY;//⽅法⼆⽤系统宏定义颜⾊属性
SetConsoleTextAttribute(hOut, wr2);
cout << "hello world!" << endl;
/*移动⽂本位置位置
BOOL ScrollConsoleScreenBuffer(HANDLE hConsoleOutput, CONST SMALL_RECT* lpScrollRectangle, CONST SMALL_RECT* lpClipRectangle,                                  COORD dwDestinationOrigin,CONST CHAR_INFO* lpFill);
// 句柄// 裁剪区域// ⽬标区域 // 新的位置// 填充字符*/
//输出⽂本
SetConsoleTextAttribute(hOut, 0x0f);
cout << "01010101010101010101010101010" << endl;
cout << "23232323232323232323232323232" << endl;
cout << "45454545454545454545454545454" << endl;
cout << "67676767676767676767676767676" << endl;
SMALL_RECT CutScr = {1, 2, 10, 4}; //裁剪区域与⽬标区域的集合⾏成剪切区域
SMALL_RECT PasScr = {7, 2, 11, 9}; //可以是NULL,即全区域
COORD pos = {1, 8};    //起点坐标,与裁剪区域长宽构成的区域再与⽬标区域的集合为粘贴区
//定义填充字符的各个参数及属性
SetConsoleTextAttribute(hOut, 0x1);
CONSOLE_SCREEN_BUFFER_INFO Intsrc;
GetConsoleScreenBufferInfo(hOut, &Intsrc);
CHAR_INFO chFill = {'A',  Intsrc.wAttributes}; //定义剪切区域填充字符
ScrollConsoleScreenBuffer(hOut, &CutScr, &PasScr, pos, &chFill); //移动⽂本
CloseHandle(hOut); // 关闭标准输出设备句柄
return0;
}
运⾏结果:
WORD⽂本属性预定义宏:(可以直接⽤16进制表⽰,WORD w = 0xf0;前⼀位表⽰背景⾊,后⼀位代表前景⾊)
FOREGROUND_BLUE 蓝⾊
FOREGROUND_GREEN 绿⾊
FOREGROUND_RED 红⾊
FOREGROUND_INTENSITY 加强
BACKGROUND_BLUE 蓝⾊背景
BACKGROUND_GREEN 绿⾊背景
BACKGROUND_RED 红⾊背景
BACKGROUND_INTENSITY 背景⾊加强
COMMON_LVB_REVERSE_VIDEO 反⾊
当前⽂本属性信息可通过调⽤函数GetConsoleScreenBufferInfo后,在CONSOLE_SCREEN_ BUFFER_INFO结构成员wAttributes中得到。
在指定位置处写属性
BOOL WriteConsoleOutputAttribute(HANDLE hConsoleOutput,  CONST WORD *lpAttribute, DWORD nLength,
COORD dwWriteCoord, LPDWORD lpNumberOfAttrsWritten);
//句柄, 属性, 个数, 起始位置, 已写个数*/
填充指定数据的字符
BOOL FillConsoleOutputCharacter(HANDLE hConsoleOutput, TCHAR cCharacter,DWORD nLength, COORD dwWriteCoord,
LPDWORD lpNumberOfCharsWritten);
// 句柄,字符,字符个数,起始位置,已写个数*/
在当前光标位置处插⼊指定数量的字符
BOOL WriteConsole(HANDLE hConsoleOutput, CONST VOID *lpBuffer, DWORD nNumberOfCharsToWrite,
LPDWORD lpNumberOfCharsWritten,LPVOID lpReserved);
//句柄, 字符串, 字符个数, 已写个数, 保留*/
向指定区域写带属性的字符
BOOL WriteConsoleOutput(HANDLE hConsoleOutput, CONST CHAR_INFO *lpBuffer, COORD dwBufferSize,
COORD dwBufferCoord,PSMALL_RECT lpWriteRegion );
// 句柄 // 字符数据区// 数据区⼤⼩// 起始坐标// 要写的区域*/
在指定位置处插⼊指定数量的字符
BOOL WriteConsoleOutputCharacter(HANDLE hConsoleOutput, LPCTSTR lpCharacter, DWORD nLength,
COORD dwWriteCoord, LPDWORD lpNumberOfCharsWritten);
// 句柄// 字符串// 字符个数// 起始位置// 已写个数*/
填充字符属性
BOOL FillConsoleOutputAttribute(HANDLE hConsoleOutput, WORD wAttribute,DWORD nLength,
COORD dwWriteCoord, LPDWORD lpNumberOfAttrsWritten);
//句柄, ⽂本属性, 个数, 开始位置, 返回填充的个数*/
// 设置代码页,
SetConsoleOutputCP(437);如(简体中⽂)设置成936
3.光标操作控制
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
cout << "hello world!" << endl;
/
/设置光标位置
//SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD dwCursorPosition);
//设置光标信息
//BOOL SetConsoleCursorInfo(HANDLE hConsoleOutput, PCONST PCONSOLE_CURSOR_INFO lpConsoleCursorInfo);
//获取光标信息
//BOOL GetConsoleCursorInfo(HANDLE hConsoleOutput,  PCONSOLE_CURSOR_INFO lpConsoleCursorInfo);
//参数1:句柄;参数2:CONSOLE_CURSOR_INFO结构体{DWORD dwSize;(光标⼤⼩取值1-100)BOOL bVisible;(是否可见)}    Sleep(2000);//延时函数
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD w = {0, 0};
SetConsoleCursorPosition(hOut, w);
CONSOLE_CURSOR_INFO cursorInfo = {1, FALSE};
Sleep(2000);//延时函数
SetConsoleCursorInfo(hOut, &cursorInfo);
CloseHandle(hOut); // 关闭标准输出设备句柄
return0;
}
运⾏结果:
输出hello world!后延时两秒,光标从第⼆⾏移到⾏⾸,再2秒后光标隐藏不显⽰;
4.键盘操作控制
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
HANDLE hOut;
//清除函数
void cle(COORD ClPos)
{
SetConsoleCursorPosition(hOut, ClPos);
cout << "" << endl;
}
//打印函数
void prin(COORD PrPos)
{
SetConsoleCursorPosition(hOut, PrPos);
cout << "hello world!" << endl;
}
//移动函数
void Move(COORD *MoPos, int key)
{
switch(key)
{
case72: MoPos->Y--;break;
case75: MoPos->X--;break;
case77: MoPos->X++;break;
case80: MoPos->Y++;break;
default: break;
}
}
int main()
{
cout << "⽤⽅向键移动下⾏输出内容" << endl;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);//取句柄
COORD CrPos = {0, 1};//保存光标信息
prin(CrPos);//打印
//等待键按下
while(1)
{
if(kbhit())
{
cle(CrPos);//清除原有输出
Move(&CrPos, getch());
prin(CrPos);
}
}
return0;
}
运⾏结果:
可以⽤⽅向键任意移动hello world!
注意区分 getch(); getche(); getcher();函数
综合案例,推箱⼦,俄罗斯⽅块(待续。。。)