/*
该实现程序之所以能将代码精简到24行(不含空行及注释行),是因为调用了函数:memset,strlen,itoa。
这三个函数作用分别是清空数组、测试字符数组长度、int转换为char类型。
这么做不知是否违反了该题的要求?我总感觉题目似乎是要求我们只能用本章第一节所搭建的“精简C语言开发
环境”来实现,也即任何事情都要亲历亲为,这样才能体会到C语言和汇编语言的内在联系。
不过在此我也借用王爽老师的“知识屏蔽”理论来为自己开脱一下哈:如果在其他细节上耗费太多的精力,我
们的研究也就偏离了主题! ^_^
解题思路如下:
1、循环检测格式字符串 AStr 中的每一个字符;
2、若该字符为普通字符,直接附加到字符数组 strPrint 的后面;
若该字符加上后一位字符为“%c”或“%d”,则读取参数列表中相应的参数,转换成字符数组附加到
strPrint 的后面;
3、循环将 strPrint 数组中每一个字符输出至屏幕。
字符显示输出时是仿照试验5的例2,直接输出到显存中,定位在屏幕第10行偏左。
程序在虚拟机 VMware + DOS6.22 + TC2.0 环境下测试通过。
*/
#include <stdlib.h>
void myprintf(char[],...); /* 函数声明 */
main()
{
myprintf("It is %c,%d,and %d",'A',18,56); /* 调用测试 */
}
/* 函数实现
AStr[]:格式字符数组(字符串),后跟不定数量的 char 或 int 类型参数,但由于受strPrint字符数组大小
限制,参数并不能无限增加。若需增加参数容量,只需修改该数组大小即可。
如:char strPrint[1000];
*/
void myprintf(char AStr[],...)
{
int nCount = 0, nLen, i, nTemp; /* nCount累计%参数的数量 */
char strPrint[100] = {0}, strTemp[7] = {0}; /* strPrint字符数组大小决定函数能接受的参数量 */
nLen = strlen(AStr); /* nLen:格式字符串中的字符数量 */
for(i = 0; i<nLen; i++)
{
memset(strTemp, 0, 7); /* 每次循环开始,清空临时字符串 */
/* 如果获取的字符为 %c 或 %d */
if ((AStr[i] == '%') && ((AStr[i+1] == 'c') || (AStr[i+1] == 'd')))
{
nTemp = *(int *)(_BP + 6 + nCount + nCount); /* 直接从内存获取对应参数值 */
if(AStr[i + 1] == 'c')
strTemp[0] = (char)nTemp; /* 标记为 char 型的则强制转换为字符 */
else
itoa(nTemp, strTemp, 10); /* 标记为 int 型的转换为字符数组 */
nCount++; /* nCount累计%参数的数量,以便下一循环调用,为参数寻址 */
i++; /* 跳过下一位格式字符 */
}
else
{
strTemp[0] = AStr[i]; /* 普通字符直接赋值到临时字符串 */
}
strcat(strPrint, strTemp); /* 临时字符串的字符连接到需打印的字符后面 */
}
/* 统计需显示的字符个数,应用一个循环将之全部显示到屏幕 */
nCount = strlen(strPrint);
for(i = 0; i < nCount; i++)
*(char far *)(0xb8000000 + 160 * 10 + 40 + i + i) = strPrint[i];
} |