登录

在这个站点登录

保存我的登录记录

<<忘记密码?

还没有账号?点此注册>>

Jerry

C语言控制台自动生成窗体

分享到:

本文已被浏览3935

C语言那个黑框子真是受够了,颜色丑爆了不说,搞个类似图形界面的样式都得提前用记事本配Fixedsys字体用制表符一行一行的对齐,否则奇丑无比,所以今天在这里分享一个自己闲来无事瞎搞的一个自动生成窗体的函数,配有测试用例。

这个问题自从C语言大作业开始就让我很头大,因为1000行代码里面竟然有600行是我用制表符凑出来的“图形”界面,实在是有够臃肿的了,并且前几天偶然发现了一个重大问题,直接打开C语言编译出来的exe文件,会发现乱码丛中printf出来的内容就这么原文显示。。。。。。真是没得说了。。。。。。

废话少说上代码!

#include 
#include 
#include 
//如此碉堡的函数一定要整一个碉堡的名字,就叫PrintW(Print Window,灵感来自printf)
/**
函数原型:PrintW(const char *title,const char *title2,const char *content,const char *functions,int Width,int Height)
	const char *title		主标题
	const char *title2		副标题
	const char *content 	窗体内容
	const char *functions	操作提示
	int Width				窗体宽度
	int Height				窗体高度
**/
void PrintW(const char *title,const char *title2,const char *content,const char *functions,int Width,int Height) {
	int i=0,cur=0,cl=0;
	char bqsm[]="版权所有,盗版必究!";
	char cmd[30];
	//调整窗体大小
	//先造一个命令行命令,不解释,Width+1是为了防止最后一个字符顶出来一行.
	sprintf(cmd,"mode con: cols=%d lines=%d",Width+1,Height);
	system(cmd);
	//绘制第一行窗体框子
	printf("╔");
	//这个比较有意思,注意一个双线制表符是占2个宽度的
	for(i=0; i<(Width-4)/2; i++) printf("═");
	printf("╗n");
	//绘制主标题,现在是不支持换行的,想支持也行,照着后面窗体内容的改
	for(cur=4,cl=0; cl<strlen(title);) {
		//先绘制文字前面的一个竖线
		printf("║");
		//主标题要居中的,计算一下前面有多少个空格
		for(i=0; i<(Width-4-strlen(title))/2; i++) printf(" ");
		//这会先不解释,看后面窗体内容
		for(;cur<width-4;) {
			if(title[cl]<0) { printf("%c%c",title[cl],title[cl+1]); cur+=2; cl+=2; } else if(title[cl]>0) {
				printf("%c",title[cl]);
				cur++;
				cl++;
			} else {
				break;
			}
		}
		//居中后面还有内容
		for(i=0; i<(Width-4-strlen(title))/2; i++) printf(" ");
		printf("║n");
	}
	//绘制副标题:看上面主标题,原理一样
	for(cur=4,cl=0; cl<strlen(title2);) {
		printf("║");
		//这个是靠右对齐的,所以略有不同
		for(i=0; i<width-6-strlen(title2); i++) printf(" ");
		for(; cur<width-4;) {
			if(title2[cl]<0) { printf("%c%c",title2[cl],title2[cl+1]); cur+=2; cl+=2; } else if(title2[cl]>0) {
				printf("%c",title2[cl]);
				cur++;
				cl++;
			} else {
				break;
			}
		}
		//这里的竖线前面有俩空格,所以上面顶空格时候回出现减6而不是减4
		printf("  ║n");
	}
	//绘制中间分隔符
	printf("╟");
	for(i=0; i<(Width-4)/2; i++) printf("─");
	printf("╢n");
	//绘制窗体内容
	//重点来了,cur是记录光标位置的,默认为4意思是已经排掉开始结尾的竖线了(2*2中文字,按英文字符算)
	//cl是字符串定位用的(按英文字符算)
	for(cur=4,cl=0; cl<strlen(content);) {
		printf("║");
		//因为输进来的content长度不定,所以要考虑分行,每一行光标位置都要初始化
		for(cur=4;cur<width;) {
			//判断是否到达结尾或者换行符
		    if(content[cl]=='n'||content[cl]=='�'){
				//如果是换行符,后面一定要填满空格
                for(;cur<width;cur++) printf(" ");
				//别忘了把回车符跳过去
                cl++;
		    }else if(content[cl]<0) { //上网查资料发现中文字占两字符,并且是负数,一次打印两个 printf("%c%c",content[cl],content[cl+1]); //光标,字符定位移动两个字符 cur+=2; cl+=2; } else if(content[cl]>0) {
				//单字符(英文,数字)直接输出就行了
				printf("%c",content[cl]);
				//光标,字符定位移动一个字符
				cur++;
				cl++;
			}
		}
		printf("║n");
	}
	//绘制分割线
	printf("╟");
	for(i=0; i<(Width-4)/2; i++) printf("─");
	printf("╢n");
	//绘制操作提示:原理同上
	for(cur=4,cl=0; cl<strlen(functions);) {
		printf("║ ");
		//cur=5是因为上面字符串后面有个空格
		for(cur=5;cur<width;) {
		    if(functions[cl]=='n'||functions[cl]=='�'){
                for(;cur<width;cur++) printf(" ");
                cl++;
		    }else if(functions[cl]<0) { printf("%c%c",functions[cl],functions[cl+1]); cur+=2; cl+=2; } else if(functions[cl]>0) {
				printf("%c",functions[cl]);
				cur++;
				cl++;
			}
		}
		printf("║n");
	}
	//绘制分隔符
    printf("╟");
	for(i=0; i<(Width-4)/2; i++) printf("─");
	printf("╢n");
	//绘制版权声明:同上
    for(cur=4,cl=0; cl<strlen(bqsm);) {
		printf("║");
		for(i=0; i<(Width-4-strlen(bqsm))/2; i++) printf(" ");
		for(; cur<width-4;) {
			if(bqsm[cl]<0) { printf("%c%c",bqsm[cl],bqsm[cl+1]); cur+=2; cl+=2; } else if(bqsm[cl]>0) {
				printf("%c",bqsm[cl]);
				cur++;
				cl++;
			} else {
				break;
			}
		}
		for(i=0; i<(Width-4-strlen(bqsm))/2; i++) printf(" ");
		printf("║n");
	}
	//绘制底部边框
	printf("╚");
	for(i=0; i<(Width-4)/2; i++) printf("═"); printf("╝n"); } //使用实例 int main() { char title1[100]; char title2[100]; char content[1000]; char function[100]; int W,H,WM; printf("请输入主标题:"); gets(title1); WM=strlen(title1)+4; printf("请输入副标题:"); gets(title2); if(strlen(title2)+4>WM){
        WM=strlen(title2)+4;
	}
	printf("请输入窗体内容:");
	gets(content);
	printf("请输入操作提示:");
	gets(function);
	printf("请依次输入窗体宽度与高度(宽度最少%d):",WM);
	WH:scanf("%d%d",&W,&H);
	if(W<wm){
        printf("您输入的宽度值小于最短长度(%d),请重新输入:");
        goto WH;
	}
	PrintW(title1,title2,content,function,W,H);
	system("pause");
	return 0;
}

最后贴上一个对应位置的图:
示意图
目前测试是没什么bug的,本来想着是弄个自动行宽列高的,但是还是懒懒哒没没弄…..

 手机扫描左边的二维码,立刻将文章收入手机!
 微信扫描左边二维码,点击右上角即可分享到朋友圈!
严禁任何非授权的采集与转载,转载须经站长同意并在文章显著位置标注本文连接,站长保留追究法律责任的权利.

评论

  1. vjudge1
    #1

    A Chinese character holds 2 bytes only if it is encoded with GB2312 encoding. As for GB18030 or UTF-8 encoding, it may occur 3 bytes. Fortunately, almost all Chinese use Windows so it’s okay.

    2015-05-11
  2. Jerry
    #2

    Of course I know.But can I change GB2312 into UTF-8?
    PS:I know you come from UPC!

    2015-05-11

 您需要 先登录 才可以回复.