开篇预告
前段时间,我在发布了一篇介绍“轻松玩转windows控制台”的文章,被不少粉丝私信批评,甚至还有个别言辞激烈的。
是因为文章写的不好吗?应该不是,因为两天时间就突破了90多个收藏,说明大家还是挺喜欢这种实用的、技巧的技术文章,但是为什么还是被批评呢?
因为文章通篇以代码为主,虽然能很多,但并没有详细的解释,导致大家在用的时候,有很多地方出现问题。
基于此,我决定围绕“轻松玩转windwos控制台”主题,写一个系列的文章,通过详细介绍控制台方面的各种操作技巧,从而c语言初学者的学兴趣。
我大致的规划主要分为这几块:
第一个系列是对控制台的各种“魔改”,包括标题修改、输出文字的字体大小、字体样式、文字颜、屏幕背景颜、控制台窗口的、居中显示、窗口大小、以及文字在窗口内任意位置的显示、中文字符的正确显示等等。
这个系列看完之后,就开始发布控制台窗口的形化操作的系列文章。
比如控制台如何控制鼠标、键盘,如何将屏幕背景改成彩,如何在控制台内实现效果等等。为后面第三个系列控制台形打下基。
第三个系列我准备围绕一个的一步步实现来发布文章,可以是一个超级玛丽,或者一个台球都可以,本身我早就已经调测运行。
话不多说,开始我们的第一个“玩转之旅”。
控制台介绍
本段是控制台的基介绍,大家不感兴趣,可以直接跳过,也不影响后面阅读。
我们用c语言刚刚编写程序时,一般都是会在屏幕上弹出一个黑乎乎的窗口,然后黑底白字的显示一行行内容。这个黑乎乎的窗口界面,我们一般称为“控制台”,是Console,而在控制台界面内运行的程序,我们一般称为“控制台程序”。
我们把通过控制台运行程序的方式,称为CUI,即Comnd User Intece,命令用户界面。相对应的,还有一种形化用户界面,GUI,即Graphi User Intece。有时候,我们也把CUI模式称为CLI模式,即Comnd Line Intece ,命令行界面,都可以。
我们一般通过执行命令进入控制台窗口,从而运行控制台程序。
以上这些都是基的概念,后面文章中用到什么就介绍什么,尽量降低复杂度。
控制台标题(Console Ttile)
我们先从控制台标题入手。
控制台程序启动时,窗口上方会有一个title(标题)。这个title显示的是程的路径和程序名称。这个title字符串我们称为“原始的窗口标题名称”,即oginal title。如:
这个字符串显示的真的很丑,我们一般都会改成我们喜欢的内容,如下所示:
围绕控制台窗口的标题,可以实现三个能。分别是“修改控制台标题”、“获取控制台标题”、“获取原始控制台标题”。控制台标题被我们修改以后,有时候我们可能需要知道程序所在的路径和程序名称,通过“获取原始控制台标题”这个能就很方便。下面来看一下这3个能对应的函数如何使用的, 并简单的介绍下windows的win32API调用。
注释:如果对Win32API不感兴趣,可以直接代码使用即可。
能:修改控制台标题
若修改控制台当前标题,需要用到的函数如下:
BOOL SetConsoleTitle(LPCTSTR lpConsoleTitle);
在学如何使用这个函数时,我们先介绍一下一些windos程序设计的基本概念,以便于后面能熟练的使用各种控制台函数。
对初学者而言,使用windows的API函数,应该会有段很痛苦的适应过程。因为微软把c/c++的基本数据类型和自定义数据类型,都采用了命名法进行了封装,我本人对这个命名法是非常厌恶的,但是还是要学下。
函数名: SetConsoleTitle,设置当前控制台标题。参数类型:LPCTSTR,这是微软队自定义的数据类型,我们来下。
L表示long类型,用来表示长整型数据;P是pointer,表示指针类型;LP表示长整型指针(即32位或位指针类型,取决于是32位或位);C表示const,LPC表示这个指针类型指向的数据是常量数据;T是type,用来表示通用类型的含义(泛型),表示有unicode版本,或者ANSI版本,暂时不用理会;STR是字符串stng的含义。
下面我列个表,就看的比较清爽了。
- L:long类型P:pointer,指针类型LP:长整型指针C:constLPC:指针指向常量T:type,泛型(暂时忽略)STR:stng,字符串LPCTSTR:LP + C + (T) + STR
由此可知,LPCTSTR,就是一个指向字符串常量的指针(字符串本身就是常量数据),可以近似理解成c语言中的const char*。
返回值:BOOL
BOOL,就是布尔类型,其实就是一个int类型:
typedef int BOOL;
如果真,就是TRUE,假就是FALSE。其实TRUE就是1,FALSE就是0。
本函数的参数是输入型参数(什么是输入型参数和输出型参数,可以查看我的这篇文章:)
这个参数在使用之前,其所在的外部变量是一个字符指针类型,必须被初始化,并且已经存放了新的标题字符串,字符个数必须小于 K(等于*1024个字节,谁能用这么多?)当函数执行成,当前标题修改成新的字符串时,就返回为TRUE,执行失败就返回FALSE。
我们来写一个演示代码:
#include #include int in { LPTR newStr = "hello,title!" ; if(SetConsoleTitle(newStr) == TRUE){ pntf("Title is changed!\n"); } ("pse"); retn 0; }
首先,文件的后缀需要是.cpp或C++源文件的格式,而不能是.c的后缀了。
其次,需要包含头文件,因为对控制台操作的函数,都是这个头文件提供的。我们需要先定义一个字符串,存放新的标题。
当然,你也可以用 char* 来定义,但是建议好和windows编程风格保持一致,就用这个非常别扭的 LPTR类型,然后判断是否设置成。
随后的函数,参数是一个字符串,这个字符串实际上就是一个DOS命令,这里是一个暂停命令。如果没有这条语句,运行这个程序时,屏幕会一闪而过。运行效果如:
窗口中的“请按任意键继续”,就是(“pse”);这行代码中的pse暂停命令起的作用。当然,为了简洁,你也可以直接写成如下形式:
#include #include int in { SetConsoleTitle("hello,title!"); ("pse"); retn 0; }
但是,好不要这么写,因为随着能越来越强大(复杂),会很不利于。那么我们想显示中文行不行?我们先一下,请看下面这段代码:
#include int in { SetConsoleTitle("你好世界"); ("pse"); retn 0; }
看一下执行的效果,如:
控制台标题输出的是乱码,当然,有可能你的编译器运行后,输出的是中文。没关系,继续往下看就好了。为什么会这样?不用急。我们右击标题栏,点“属”进去,注意看,下面这个截中的红框,显示了当前使用的编码。
代码页,即Code Page,简写为CP,表明了当前控制台的编码情况。如果是437,则是英语;如果是936,则是ANSI/OEM – 简体中文默认的GBK编码;如果是950 ,则是繁体中文;如果是,则是UTF-8编码。当然,代码页有很多种,我们只需要关心一个就可以了,就是UTF-8编码。用列表显示代码页标识符和编码标准,会更清楚:
- 437 :英语936 : ANSI/OEM – GBK950 : 繁体中文 :UTF-8
如果控制台显示乱码,我们可以将当前代码页设置为,即UTF-8,就可以正确显示中文。注意,并不是因为当前代码页是936,所以就显示乱码。
显示乱码是编译器的编码规范和的编码规范不一致,需要手动修改编码规范。通过下面介绍的方法,通过修改代码页为UTF-8,可以快速解决问题,但不是的解决办法。
函数SetConsoleCP是设置控制台输入字符使用的编码标准,SetConsoleOutputCP是设置控制台输出字符的编码标准,函数如下:
BOOL SetConsoleCP(UINT wCodePageID); BOOL SetConsoleOutputCP(UINT wCodePageID);
参数类型:UINT
微软将基本数据类型int封装成INT,约定为32位的有符整数,取值范围是 – 到 。即:
typedef int INT;
而无符整型unsied int 被封装成UINT,约定为32位无符整数,取值范围为 0 到 。即:
typedef unsied int UINT;
参数的值就是代码页的标识符,比如要显示中文,UINT变量的值就是即可。
返回值是BOOL类型,前已介绍过,如果执行成,则返回TRUE,否则返回FALSE。
举例如下:
#include #include int in { SetConsoleCP;//控制台标题 SetConsoleOutputCP;//输出内容 LPTR newStr = "你好世界!" ; if(SetConsoleTitle(newStr) == TRUE){ pntf("标题修改成!\n"); } ("pse"); retn 0; }
我们看下执行结果:
我们通过SetConsoleOutputCP,设置了输出字符的代码页(Code Page,CP)为UTF-8,所以pnftf函数的输出内容,正常显示中文了,同样的输入字符显示中文,通过SetConsoleCP就可以了。
进一步的,我们在程序里,如果需要显示中文,我们需要知道当前代码页的数值是不是,如果不是,我们需要设置成6501。我们如知晓呢?
可以通过GetConsoleCP获取输入状态的代码页,GetConsoleOutputCP获取输出状态的代码页,从而进行判断。函数如下:
UINT GetConsoleCP(void); UINT WINAPI GetConsoleOutputCP(void);
这两个函数没有参数,返回值是UINT类型,也就是当前所用的代码页标识符。第一个函数返回的是输入模式的代码页标识符,第二个函数返回的是输出模式的代码页标识符。通过对代码页判断,然后始终保持当前代码页标识符为即可。
示例代码如下:
#include #include int in{ UINT codePage = GetConsoleOutputCP; if(codePage != ){ SetConsoleCP; SetConsoleOutputCP; } LPTR newStr = "你好,世界!" ; if(SetConsoleTitle(newStr) == TRUE){ pntf("标题修改成!\n"); } retn 0; }
我们现在可以随心所欲的修改窗口标题名了,并且也可以正确显示中文内容了。接下来,我们如何获取当前窗口的标题名呢?
能:获取控制台标题
通过GetConsoleTtile函数,就可以获取道当前控制台的标题。函数如下:
DWORD GetConsoleTitle(LPTSTR lpConsoleTitle, DWORD nSize );
函数名: GetConsoleTitle;第一个参数类型:LPTSTR
这个参数的类型和上面介绍的SetConsoleTtitle函数的LPCTSTR类型,很相似。本质的区别在于字母C,LPCTSTR是指向常量字符串,不允许修改,属于输入参数。而LPTSTR类型,指向的是可以被修改的一段区域,一般我们定义成一个数组,或者一段动态内存分配区域。
第二个参数类型:DWORD
windows编程规范中,把8个位(bit)当作1个字节BYTE,把2个BYTE当作1个字,即WORD,2个WORD为双字,即DOUBLE WORD,简写为DWORD。
1个DWORD类型的变量,等于4个字节,表示32 位无符整数。 范围为 0 到十进制。其实就是c语言中的 unsied long ,实际上也是这样定义的:
typedef unsied long DWORD;
返回值和第二个参数一样,也是DWORD。
第一个参数是输出型参数,接受函数的返回数据。(什么是输入型参数和输出型参数,可以查看我的这篇文章:),用来存放获取的当前窗口标题字符串。
第二个参数是要显式的说明第一个参数所指向的内存区域的大小,以字符为单位。
如果函数成,则返回值为控制台窗口标题的字符个数。如果函数失败,则返回值为零。
下面是一段演示代码:
#include #include #include #include int in{ DWORD charactor_total = MAX_PATH; LPTSTR title = (LPTSTR)lloc(sizeof(CHAR)*MAX_PATH); DWORD n = GetConsoleTitle(title,charactor_total); pntf("标题字符个数:%d\n",n); ("pse"); retn 0; }
程序执行结果如:
大家可以数一下标题的字符数,是不是91个。
能:获取原始标题
当控制台窗口标题被修改后,我们有时候需要获取窗口的原始标题,也就是程序的路径和程序全名(包括后缀),这非常有用,因为可以根据这个字符串提取出程序文件所在的目录。
获取原始标题的函数为GetConsoleOginalTitle,当窗口标题未被修改时,GetConsoleTtile和它的能是一样的,当被修改后,就出现了本质的差别,所以小心不要用错函数。
函数如下:
DWORD GetConsoleOginalTitle( LPTSTR lpConsoleTitle, DWORD nSize);
这个函数的参数和用法,就不再讲解,和GetConsoleTitle函数类似。
总 结
段誉,2024年2月9(除夕),写于合肥。
版权声明:本文由发布,不代表浮予百科立场,转载联系作者并注明出处。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件,一经查实,本站将立刻删除。:记事本 » 控制台怎么使用gdb(StraitenedTimes控制台舞台灯光打开)