c/c++ console(控制台)編程詳解
前言:
控制台文本窗口的控制是基於win32 api(win32 api可理解為微軟給我們提供的一系列函數的集合)實現的;
例1:
#include <stdio.h>int main()
{
printf("Hello World!\n");
return 0;
}
運行結果:

例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");
return 0;
}
運行結果:

例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!");
return 0;
}
運行結果:

在例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);
return 0;
}

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;
WORD 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); // 關閉標准輸出設備句柄
return 0;
}
運行結果:

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); // 關閉標准輸出設備句柄
return 0;
}
運行結果:
輸出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)
{
case 72: MoPos->Y--;break;
case 75: MoPos->X--;break;
case 77: MoPos->X++;break;
case 80: 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);
}
}
return 0;
}
運行結果:

可以用方向鍵任意移動hello world!
注意區分 getch(); getche(); getcher();函數

