重构ASCII码表输出程序
分析
使用函数可以有序的组织程序结构,现在我们尝试用函数重构一下ASCII码表输出程序。对于改进后的版本,有如下功能需求:
- 表头输出:每个编码输出其16进制、10进制及字符显示。
- 输出列出可设定,最少1列最多3列。
- 保持输出的工整性。
- 程序结构清晰,易于阅读。
回顾之前的程序,我们输出了表头,然后是ASCII表的内容,这两部分内容可以划分到独立的函数中,基于需求2,这两个函数应该接收一个代表列数的整数值,它们的原型如下:
- void print_header(int columns);
- void print_ascii(int columns);
对于像回车、换行、制表位等特殊字符会导到ASCII码表输出时位置错乱,之前的实现中,我们将这些特殊控制字符空格化,这里依旧采取这种策略,更进一步将它也安排到了一个函数中,该函数接收一个编码值,并返回最终的输出字符,其原型如下:
- int escape_check(int ch);
实现
特殊字符处理
函数escape_check接收当前被处理的ASCII码,判断它是否需要转换为空格显示,如果是,返回空格,否则返回字符本身。这里使用了段注释的方式描述了函数的相关信息,段注释将以/*开头*/结尾的多行文本解释为注解,显然段注释是不能嵌套的。
/*
作用:检测是否需要将特殊字符转换为空格
参数:ch---输入字符
返回值:需要特化时返回空格,否则返回原字符
*/
int escape_check(int ch)
{
if (ch == 8 || ch == 9 || ch == 10 || ch == 13)
return 32;
else
return ch;
}
输出表头
我们使用for循环语句输出表头,列之间有一个水平制表符间距,表头与ASCII表用短横线分隔。
/*
作用:输出表头
参数:columns---列数
返回值:无
*/
void print_header(int columns)
{
// 输出表头
for (int i = 0; i < columns; i++)
{
printf("DEC\tHEX\tCHR");
// 不是最后一列时输出列间距
if (i != columns - 1)
printf("\t");
}
printf("\n");
// 输出表头分隔线
for (int i = 0; i < columns; ++i)
{
printf("-------------------");
if (i != columns - 1)
printf("\t");
}
printf("\n");
}
输出ASCII码表
下面的代码展示了两种可能的方案:
- 使用一个for循环+多个if语句实现,缺陷就是每执行一次,循环就停顿一下。
- 优先判断列数,每个分支一个循环处理,程序执行的比较流畅。
void print_ascii(int columns)
{
//============ 方案一
for (int i = 0; i < 128; i += columns)
{
if (columns == 1)
{ /* 输出... */ }
else if (columns == 2)
{ /* 输出... */ }
}
//============ 方案二
if (columns == 1)
{
for (int i = 0; i < 128; i += columns)
{ /* 输出... */ }
}
else if (columns == 2)
{
for (int i = 0; i < 128; i += columns)
{ /* 输出... */ }
}
}
下面是我们采用第1种方案的一种实现。
//=============================================================================
void print_ascii(int columns)
{
for (int i = 0; i < 128; i += columns)
{
printf("%d\t0x%x\t%c", i, i, escape_check(i));
if (columns >= 2)
printf("\t%d\t0x%x\t%c", i + 1, i + 1, escape_check(i + 1));
// 输出第3列并阻止输出大于127的值
if (columns >= 3 && (i + 2) < 127)
printf("\t%d\t0x%x\t%c", i + 2, i + 2, i + 2);
printf("\n");
}
}
//=============================================================================
int main()
{
// 从输入或配置文件读取列数
int columns = 3;
// 保证列的有效性
if (columns < 1) columns = 1;
else if (columns > 3) columns = 3;
print_header(columns);
print_ascii(columns);
return 0;
}