C/C++ 控制台高级操作(非常详细)


C/C++实战入门到精通 https://blog.csdn.net/weixin_50964512/article/details/125710864

前言

对于初学者来说,控制台(即黑窗口)是最早接触,同时也是最利于学习知识点的.

一般情况,我们只需要使用其输入与显示功能即可

但有时候我们可能也需要对控制台进行更加高级的操作,比如改变标题,改变颜色,改变大小等,这时候就需要对window关于控制台的 api要有一定的了解

所以我便作了本文,详细介绍我们可以对控制台进行哪些高级操作

一、使用Win API条件

1.需要安装window开发工具包,因为我习惯于使用VS(visual studio),即只需要安装C++开发环境即可
在这里插入图片描述
如果想从事C/C++的工作,也建议使用vs,因为这个软件是目前最先进的C/C++开发软件

2.包含头文件Windows.h

#include<Windows.h>

需要说明的是,这个头文件包含了大多数win api函数的定义,绝不仅仅只包含控制台api

查看操作控制台的全部可使用API函数

二、详细操作

1.修改和获取标题

使用函数:SetConsoleTitleA,GetConsoleTitleA

BOOL WINAPI SetConsoleTitleA(
  _In_ LPCTSTR lpConsoleTitle //填标题
);
DWORD WINAPI GetConsoleTitle(
  _Out_ LPTSTR lpConsoleTitle, //获取标题的缓存区
  _In_  DWORD  nSize //该缓存区的大小
);

使用:

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	char buf[0xFF];
	GetConsoleTitleA(buf,0xFF); //获取原标题
	cout << buf << endl;

	SetConsoleTitleA("test"); //设置一个新标题

	GetConsoleTitleA(buf, 0xFF);//获取新标题
	cout << buf << endl;
}

在这里插入图片描述

2.修改大小

这里主要使用两个函数: SetConsoleWindowInfo,SetConsoleScreenBufferSize,还有一个常用函数GetStdHandle

关系:
GetStdHandle获取控制台的句柄(句柄可以理解为控制台的标志,我们可以通过这个标志来找到它,更改它)

SetConsoleScreenBufferSize:设置控制台缓存区的大小,就相当于一个二维数组,控制台显示内容的方式就是将该二维数组的内容映射到屏幕上

SetConsoleWindowInfo:设置控制台大小,必须要小于控制台缓存区的大小(如果控制台比缓存区还大了,那就没东西显示了,很好理解)

原型:

HANDLE WINAPI GetStdHandle(
  _In_ DWORD nStdHandle //获取指定的句柄,输出:STD_OUTPUT_HANDLE,输入:STD_INPUT_HANDLE,错误:STD_ERROR_HANDLE,具体要哪种句柄,看实际需要
);
BOOL WINAPI SetConsoleWindowInfo(
HANDLE     hConsoleOutput,  //标准输出句柄
BOOL       bAbsolute, //是否以全局窗口
SMALL_RECT *lpConsoleWindow //要设置的大小
);
BOOL WINAPI SetConsoleScreenBufferSize(
HANDLE hConsoleOutput, //标准输出句柄
COORD  dwSize //要设置的大小
);

使用:

#include<Windows.h>
#include<iostream>
using namespace std;
bool SetSize(int width, int height)
{
	HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE); //获取输出句柄
	SMALL_RECT wrt = { 0, 0, width - 1, height - 1 }; //设置宽高
	bool ret = SetConsoleWindowInfo(hOutput, TRUE, &wrt); // 设置窗体尺寸
	if (!ret) return false;
	COORD coord = { width, height };
	ret = SetConsoleScreenBufferSize(hOutput, coord); // 设置缓冲尺寸
	return ret;
}
int main() {
	SetSize(50,40);
}

在这里插入图片描述

3.显示与隐藏光标,更改光标大小

主要用到的函数为:SetConsoleCursorInfo
但为了不改变其它属性,还用到了:GetConsoleCursorInfo
函数原型:

BOOL WINAPI GetConsoleCursorInfo(
 HANDLE          hConsoleOutput, //标准输出句柄
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo //包含光标信息的结构体
);
BOOL WINAPI SetConsoleCursorInfo(
 HANDLE    hConsoleOutput, //标准输出句柄
CONSOLE_CURSOR_INFO *lpConsoleCursorInfo  //包含光标信息的结构体
);

光标信息结构体:

typedef struct _CONSOLE_CURSOR_INFO {
    DWORD  dwSize; //光标大小 值可取1-100之间
    BOOL   bVisible; //光标是否可见
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

如果只想隐藏或显示光标,则,先获取现有光标的属性,然后将是否显示光标的属性bVisible更改,最后再设置回去

当然如果都想更改,可不调用GetConsoleCursorInfo函数.手动设置dwSize和bVisible然后传入SetConsoleCursorInfo函数

使用:

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cInfo{};
	GetConsoleCursorInfo(hOutput, &cInfo); //获取现有光标信息
	cInfo.bVisible = false; //false为隐藏窗口,true为显示窗口
	SetConsoleCursorInfo(hOutput, &cInfo);  //重新设置光标信息
}

结果:
在这里插入图片描述
不再有光标闪烁

4.改变光标位置

这个很简单,用到一个API函数:SetConsoleCursorPosition
原型:

BOOL WINAPI SetConsoleCursorPosition(
HANDLE hConsoleOutput, //标准输出句柄
COORD  dwCursorPosition //要设置的位置信息
);

使用:

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD coo;
	coo.X = 10;
	coo.Y = 10;
	SetConsoleCursorPosition(hOutput, coo);
}

结果:
在这里插入图片描述

5.禁止更改窗口大小,最小化,最大化

这里用到了三个函数:
GetWindowLongPtrASetWindowLongPtrAGetConsoleWindow

HWND GetConsoleWindow();//返回控制台窗口的句柄
LONG_PTR GetWindowLongPtrA(
HWND hWnd, //窗口句柄
int  nIndex //要获取的窗口属性类别,这里我们需要窗口样式GWL_STYLE
);
LONG_PTR SetWindowLongPtrA(
  [in] HWND     hWnd, //窗口句柄
  [in] int      nIndex,//要设置的窗口属性类别,这里我们需要设置窗口样式GWL_STYLE
  [in] LONG_PTR dwNewLong //要设置的值
);

逻辑:
先获取控制台窗口样式,然后去除掉可更改,可最大,可最小化的属性,然后再设置回去

代码:

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	HWND hWnd=GetConsoleWindow(); //获取窗口句柄
	LONG_PTR sty=GetWindowLongPtrA(hWnd, GWL_STYLE); //获取窗口样式
	sty = sty & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX; //去除可变化大小,最大,最小化按钮,~是取反,&是与,这是位运算相关的知识了
	SetWindowLongPtrA(hWnd, GWL_STYLE, sty); //设置窗体不可更改大小,不可最大化
}

结果:
在这里插入图片描述
最大最小按钮消失,且不可改变大小

6.改变字体颜色

使用到一个函数:SetConsoleTextAttribute
函数原型:

BOOL WINAPI SetConsoleTextAttribute(
HANDLE hConsoleOutput, //标准输出句柄
WORD   wAttributes //要设置的文本属性,包括字体颜色,字体背景颜色等属性
);

可选择属性,用 | 符号组合
在这里插入图片描述
使用:

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输出句柄
	SetConsoleTextAttribute(hOutput,FOREGROUND_BLUE|BACKGROUND_GREEN|COMMON_LVB_UNDERSCORE); //设置文本颜色蓝色,背景色绿色,有下划线
	cout << "this is a test!";
}

在这里插入图片描述
可以看到已经变成蓝色字,绿色背景,有下划线的样式了

确实有点小丑,大家可以自行组合各种属性,找到满意的样式

7.更改字体

理论上来说,可以使用win API对控制台窗口字体进行更改

我自己研究了一下,发现通过调用API进行字体设置过于复杂,需要调用大量API,学习成本太大,所以这里就不加展示

这里介绍一种更加友好的设置字体:

1.点击win+R快捷键,左下角出现该窗口
在这里插入图片描述
2.输出cmd,点击Enter,出现黑窗口
在这里插入图片描述
3.右键顶部黑窗口外框,点击属性
在这里插入图片描述
4.选择字体,可以更改自己喜欢的字体及颜色,大小
在这里插入图片描述
5.点击确认即可

注意:使用其它软件运行时,可能使用的不是这个系统cmd控制台(及黑窗口)

比如我这里就有多个
在这里插入图片描述
这时候上面的更改就是无效的

最好的办法就是先让程序运行一次,出现黑窗口,然后从上面第3步开始进行设置

之后运行,控制台就会保留当前的设置

8.改变背景颜色

官方文档中,我没有找到可以改变整个窗口背景颜色的API,但是可以采用批处理命令实现

该方法可同时改变背景色和文字颜色

官方文档:
在这里插入图片描述
使用方法:

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	system("color 0C"); //设置背景为黑色,字体为淡红色
	cout << "this is a test!";
}

system可以用来执行批处理命令
在这里插入图片描述

9.分离当前控制台

使用FreeConsole函数即可
在这里插入图片描述
当使用了改函数,所有输出结果就接收不到了

10.分配一个控制台

这时就可以使用:AllocConsole,重新分配一个控制台

#include<Windows.h>
#include<iostream>
using namespace std;
int main() {
	FreeConsole(); //分离原有的控制台
	cout << "this is a test";
	AllocConsole(); //分配一个新的控制台
	cout << "this is a test llllllllllllllll";
}

结果:
在这里插入图片描述
此时又出现了一个新的控制台,并将结果输出到了新控制台上

  • 39
    点赞
  • 251
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
### 回答1: C#是一种广泛使用的编程语言,也可以与C代码进行交互。调用C代码可以实现更高级的功能和操作。下面以一些示例代码来说明如何在C#中调用C代码: 首先,我们需要创建一个包含C代码的动态链接库(DLL)文件。C代码使用一种称为P/Invoke的技术来与C#进行交互。我们可以使用C语言编写我们的函数,并确保它们通过将它们标记为导出函数可供C#访问。 一旦我们有了动态链接库文件,我们就可以在C#中进行调用。我们需要在C#代码中使用DllImport属性来指定具体的DLL文件和函数。 以下是一个示例,演示如何调用C代码中的add函数: ```c // C代码 // 将以下代码保存为一个名为c_code.c的文件 __declspec(dllexport) int add(int a, int b) { return a + b; } ``` ```csharp // C#代码 // 将以下代码保存为一个名为Program.cs的文件 using System; using System.Runtime.InteropServices; class Program { [DllImport("c_code.dll")] public static extern int add(int a, int b); static void Main() { int result = add(2, 3); Console.WriteLine("The result is: " + result); } } ``` 在上述示例中,C代码文件c_code.c包含了一个add函数,它将两个整数相加并返回结果。然后,在C#代码中,我们使用DllImport属性标记了add函数,并指定了C代码的DLL文件名。在Main函数中,我们调用了add函数,并将结果打印到控制台。 通过这种方法,我们可以在C#中调用C代码并使用C代码中定义的函数来实现更高级的功能和操作。 ### 回答2: 在C#中调用C代码的过程如下: 首先,需要将C代码编译为动态链接库(DLL)或共享库(SO)。这可以通过使用C语言的编译器将C代码编译为与目标平台相关的库文件来完成。 在C#中,可以使用Platform Invoke(P/Invoke)机制来调用C代码。P/Invoke是一种允许.NET程序与非托管代码进行交互的技术。 在C#中调用C代码需要使用[System.Runtime.InteropServices.DllImport]属性来指定C函数的名称和库文件的路径。例如,如果C函数的名称是"myFunction",并且库文件的路径是"path/to/myLibrary.dll",则可以使用以下方式调用C函数: ```csharp using System.Runtime.InteropServices; class Program { [DllImport("path/to/myLibrary.dll")] public static extern void myFunction(); static void Main(string[] args) { myFunction(); } } ``` 在C#中定义的C函数必须与C代码中的函数签名一致,并且使用正确的数据类型。如果C函数返回某个类型的值,则可以在C#中将其定义为返回相应类型的extern函数。 需要注意的是,当在C#中调用C代码时,需要确保目标平台的运行时环境已经安装了C代码所需的依赖项。否则,可能会引发运行时错误。 在使用P/Invoke调用C代码时,还需要注意数据类型的匹配,例如将C#的字符串转换为C中的char数组等。 总的来说,通过使用P/Invoke机制,可以很方便地在C#中调用C代码,并实现C#与C之间的无缝交互。 ### 回答3: C#是一种面向对象的编程语言,而C是一种过程式的编程语言。虽然两者之间存在一些差异,但是C#是可以调用C代码的。 要在C#中调用C代码,我们首先需要用到一个叫做Platform Invoke(简称P/Invoke)的机制。P/Invoke是一个能够在C#中调用非托管代码(如C代码)的功能。它通过使用DllImport特性来告诉C#需要调用的C函数的名称、所在的库等信息。 下面是一个简单的示例,展示了如何在C#中调用一个C函数: 首先,在C文件中,我们有一个名为myCFunction的函数: ``` #include <stdio.h> void myCFunction() { printf("Hello from C!"); } ``` 接下来,在C#中,我们需要使用DllImport特性来告诉编译器要调用的C函数的信息: ``` using System; using System.Runtime.InteropServices; class Program { [DllImport("myCLibrary.dll")] public static extern void myCFunction(); static void Main(string[] args) { myCFunction(); // 调用C函数 } } ``` 在这个示例中,我们使用了DllImport特性来指定要调用的C函数的库文件,函数名称等信息。然后,在C#中,我们可以直接调用这个C函数。 通过这种方式,我们可以在C#中调用任意的C函数,实现更灵活的编程。当然,在使用P/Invoke时需要遵守一定的规则和注意事项,如确保C函数的参数和返回值类型与C#中的类型匹配,避免出现类型转换错误等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余识-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值