效果如下图,标题和版权信息,代码在文末
/*************************************************************************
** Desc : PrintBlock
** Param : [in] iStartEnd 两端偏移量
** : [in] pString 要打印的字符,不能包含换行符
** Return :
** Author : hicker
*************************************************************************/
void PrintBlock(int nWindow, int nMaxChars, int iStartEnd, const char *pString)
{
int nString = strlen(pString);
int rString = (nString / (nMaxChars + 1)) + 1;
for (int i = 0; i < rString; i++)
{
char strFmt[32] = { 0 };
sprintf(strFmt, "%%-%dc", iStartEnd);
printf(strFmt, '|');
int cTitle = (i + 1 == rString && nString != nMaxChars) ? (nString % nMaxChars) : nMaxChars;
for (int j = 0; j < cTitle; j++)
{
printf("%c", pString[i*nMaxChars + j]);
}
for (int x = 0; x < (nWindow - iStartEnd - cTitle - 1); x++) printf(" ");
printf("|\n");
}
}
/*************************************************************************
** Desc : PrintW
** +=================+
** | 标题 |
** |-----------------|
** | 内容1 |
** | 内容2 |
** |-----------------|
** | 1.确定 |
** | 2.取消 |
** |-----------------|
** | 腾讯 |
** ^^^^^^^^^^^^^^^^^^^
** Param : [in] pTitle 标题。自动居中,不可包含换行符,会自动换行
** : [in] pContent 内容。最多不能超过16个换行符,且每行最多128个字符
** : [in] pTips 提示。最多不能超过16个换行符,且每行最多128个字符
** : [in] pAppVer 软件名或版权。不可包含换行符
** : [in] nWidth 字符窗口宽度。小于5时取默认值,同时如果设置或最
** 终内部计算出的nWidth大于当前控制台窗口最大宽度,将会显示凌乱
** Return :
** Author : hicker
*************************************************************************/
void PrintW(const char *pTitle, const char *pContent, const char *pTips, const char *pAppVer = NULL, int nWidth = 0) {
// 原始Title
int nTitle = strlen(pTitle);
// 内容宽度最小满足[| x |],即5个字符
if (nWidth < 5)
{
nWidth = nTitle + 4;
}
const int nMaxTitle = nWidth - 4; // 调整后的窗口内可容纳的最大Title宽
const int nMaxContent = nMaxTitle; // 调整后的窗口内可容纳的最大Content宽
const int nMaxAppVer = nMaxTitle; // 调整后的窗口内可容纳的最大AppVer宽
// 计算Title的起始位置和所需要的行数
int rTitle = (nTitle / (nMaxTitle + 1)) + 1;
int iTitle = 2; // 先假设一行容纳不下,所以应该等于2;
if (nWidth >= nTitle + 4)
{ // 若一行能够容纳
iTitle = (nWidth - nTitle) / 2;
}
// 计算Content起点
int iContent = 1;
// 计算Tips起点
int iTips = 2;
// 原始AppVer
int nAppVer = strlen(pAppVer);
// 计算AppVer的起始位置和所需要的行数
int rAppVer = (nAppVer / (nMaxTitle + 1)) + 1;
int iAppVer = 2; // 先假设一行容纳不下,所以应该等于2;
if (nWidth >= nAppVer + 4)
{ // 若一行能够容纳
iAppVer = (nWidth - nAppVer) / 2;
}
//**********依据以上值打印所有***********
//打印上沿和Title
printf("+");
for (int i = 0; i<nWidth - 2; i++) printf("=");
printf("+\n");
PrintBlock(nWidth, nMaxTitle, iTitle, pTitle);
//打印上沿和Content
printf("|");
for (int i = 0; i<nWidth - 2; i++) printf(".");
printf("|\n");
char szRowColContent[16][128] = { 0 }; // 此设置要求Content最多不能超过16个换行符,且每行最多128个字符
int nRowContent = StrUtil::Split(pContent, "\n", (char**)szRowColContent, (16 << 16) | 128);
for (int i = 0; i < nRowContent; i++) PrintBlock(nWidth, nMaxContent, iContent, szRowColContent[i]);
//打印上沿和Tips
printf("|");
for (int i = 0; i<nWidth - 2; i++) printf(".");
printf("|\n");
char szRowColTips[16][128] = { 0 }; // 此设置要求Content最多不能超过16个换行符,且每行最多128个字符
int nRowTips = StrUtil::Split(pTips, "\n", (char**)szRowColTips, (16 << 16) | 128);
for (int i = 0; i < nRowTips; i++) PrintBlock(nWidth, nMaxContent, iTips, szRowColTips[i]);
//打印上沿和szAppVer
printf("|");
for (int i = 0; i<nWidth - 2; i++) printf(".");
printf("|\n");
PrintBlock(nWidth, nMaxAppVer, iAppVer, pAppVer);
// 打印下沿
printf("|");
for (int i = 0; i<nWidth - 2; i++) printf("_");
printf("|\n");
}
int main()
{
PrintW("自适应字符窗口", "1.转发器;\n2.网站微服务;\n3.人生选择器;", "①确定\n②取消", "腾讯科技有限公司@2019", 70);
getchar();
}