《C语言接口与实现》实验——格式化(Fmt_T)

来源:互联网 发布:女生网络钓鱼 编辑:程序博客网 时间:2024/05/18 18:43

实验程序是用vc6编译,一定注意文件扩展名为c,不是cpp,下载前面几个测试程序(链表、表、原子中有下载链接)中直接将下面源程序覆盖1.c的内容即可!


再次强烈建议在这些函数上设上断点,按F11跟进去把源码走一遍,才有真正的学习效果!


源程序如下:

#include <stdio.h>#include <string.h>#include "include/Fmt.h"#include "include/Str.h"#pragma comment(lib, "libcii.lib")typedef int (*FN)(int, void *);void main(){//注意:C语言一定要将这些变量声明放在函数的头部char *s1 = NULL;////以下为【格式化】函数//Fmt_fmt((FN)fputc, stdout, "测试1: Fmt_fmt: %d, %s, %x, %f, %e, %g, 单字符: %c, 16进制:0X%x\n", 9988, "OK", 9988, 90.89, 90.89, 90.89, 101, 101);/*下面这些函数最终会调用:Fmt_vfmt 遇到【%d】时,调用:cvt_d,此静态函数已经在初始化时安装好,见书中文版P164的cvt[]初始赋值'd' = 100(ASCII值),对应:cvt_d 函数'c' = 100,对应: cvt_c 函数'e' = 101,'f' = 102, 'g' = 103,三个都是浮点数转换,下标均对应cvt_f函数,见中文版P170说明,内部都是调用了sprintf库函数来格式化'x' = 101,,对应: cvt_x 函数,留心源码的“*--p = "0123456789abcdef"[m&0xf];”部分;.............*/////Fmt_print("测试2: Fmt_print: %d, %s, %x\n", 9988, "OK", 9988);//Fmt_fprint(stdout, "测试3: Fmt_fprintf: %d, %s, %x\n", 9988, "OK", 9988);//s1 = Fmt_string("测试4: Fmt_string: %d, %s, %x\n", 9988, "OK", 9988);printf("%s", s1);////以下为【转换】函数//Fmt_register('@', Str_fmt);/*'@' = 64, 关联上 Str_fmt,Str_fmt和cvt_d,cvt_s, cvt_o,cvt_f等等是一样的定义方式观察Str_fmt的内部实现,是接受【开始偏移】和【显示长度】两个参数,因此仅适合下面Fmt_print的用法可以比较Str_fmt和cvt_s两个函数的实现(附后)*/Fmt_print("测试5: Fmt_string: %@\n", "ChinaOKYes", 0, 4);}

输出

测试1: Fmt_fmt: 9988, OK, 2704, 90.890000, 9.089000e+001, 090.89, 单字符: e, 16进制:0X65测试2: Fmt_print: 9988, OK, 2704测试3: Fmt_fprintf: 9988, OK, 2704测试4: Fmt_string: 9988, OK, 2704测试5: Fmt_string: naOKYesPress any key to continue

比较cvt_s(src/fmt.c),和Str_fmt(src/str.c)两个函数:

static void cvt_s(int code, va_list *app,int put(int c, void *cl), void *cl,unsigned char flags[], int width, int precision) {char *str = va_arg(*app, char *);assert(str);Fmt_puts(str, strlen(str), put, cl, flags,width, precision);}void Str_fmt(int code, va_list *app,int put(int c, void *cl), void *cl,unsigned char flags[], int width, int precision) {char *s;int i, j;assert(app && flags);s = va_arg(*app, char *);i = va_arg(*app, int);j = va_arg(*app, int);convert(s, i, j);Fmt_puts(s + i, j - i, put, cl, flags,width, precision);}



附:ASCII表非常有用,再附上一遍,便于查看:

The following table lists 0 - 127.

CodeCharCodeCharCodeCharCodeChar0 32[space]64@96`1 33!65A97a2 34"66B98b3 35#67C99c4 36$68D100d5 37%69E101e6 38&70F102f7 39'71G103g8**40(72H104h9**41)73I105i10**42*74J106j11 43+75K107k12 44,76L108l13**45-77M109m14 46.78N110n1547/79O111o1648080P112p1749181Q113q1850282R114r19 51383S115s20 52484T116t21 53585U117u2254686V118v2355787W119w2456888X120x2557989Y121y2658:90Z122z27 59;91[123{2860<92\124|2961=93]125}30-62>94^126~31 63?95_127

原创粉丝点击