原创 深入理解文件系统(五)

2010-3-30 21:44 2363 4 5 分类: MCU/ 嵌入式

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

 


五、使用文件字符串处理的功能。


 


1、目的


验证f_printf()函数的功能,学习变参数函数的编写和使用方法。


掌握格式化字符串的一些定义和用途


2、有关格式控制串


格式控制串总是以%开始,后跟一些参数:


%flags】【宽度】【精度控制】type


前面三个是可选,而type是必须的参数。


(1)   flag用于控制输出的 符号++-)、对齐方式-(左对齐)等


(2)   宽度只控制输出的宽度,03,当字符数小于3个时,左边补0.


(3)   精度控制,主要针对浮点数。比如12.3456  如果%.2则只输出2位,变成12.34


(4)   类型是必须的。这里主要分析这个。


3、源代码分析


int f_printf (


      FIL* fil,               /* Pointer to the file object */


      const char* str,   /* Pointer to the format string */


      ...                                /* Optional arguments... */


){   va_list arp;


      UCHAR c, f, r;


      ULONG val;


      char s[16];


      int i, w, res, cc;


 


      va_start(arp, str);      //arp实际是一个通用类指针,指向str后的第一个参数。


      for (cc = res = 0; cc != EOF; res += cc) {


             c = *str++;


             if (c == 0) break;                     /* End of string */


             if (c != '%') {                            /* Non escape cahracter */


                    cc = f_putc(c, fil);      //如果不是%,表示正常字符,写入文件


                    if (cc != EOF) cc = 1; //cc是本次写对应的字符数字。当然如果写入不成功,返回EOF,则跳出循环


                    continue;                           //res是总共写入的数字


             }


             w = f = 0;      //从此处开始表示遇到了%后的处理


             c = *str++;   //取出下一个字符


             if (c == '0') {                      /* Flag: '0' padding */


                    f = 1; c = *str++;       //如果是字符0,表示要控制宽度,flag0位标志置位。取出下一字符


             }


             while (c >= '0' && c <= '9') {  /* Precision */


                    w = w * 10 + (c - '0');


                    c = *str++;          //依次取出后面的字符,如遇到034,则w=34。字符输出 }


             if (c == 'l') {                       /* Prefix: Size is long int */


                    f |= 2; c = *str++;         //如果遇到字符'l',表示长整形,标志第1位置位。            }


             if (c == 's') {                      /* Type is string */


                    cc = f_puts(va_arg(arp, char*), fil); //如果遇到 s’标志,将arp转换为char*指针,并指向下一个参数。


                    continue;      //cc是字符串的长度,本次输入文件的字符数。


             }


             if (c == 'c') {                      /* Type is character */


                    cc = f_putc(va_arg(arp, int), fil);   //字符以int类型出现,要占四个字节。


                    if (cc != EOF) cc = 1;


                    continue;


             } r = 0;   //如果字符'0''l'后,不是sc,则下面继续处理


             if (c == 'd') r = 10;            /* Type is signed decimal */


             if (c == 'u') r = 10;            /* Type is unsigned decimal *///十进制


             if (c == 'X') r = 16;           /* Type is unsigned hexdecimal */


             if (r == 0) break;                     /* Unknown type */


             if (f & 2) {                         /* Get the value */


                    val = (ULONG)va_arg(arp, long);


             } else {


                    val = (c == 'd') ? (ULONG)(long)va_arg(arp, int) : (ULONG)va_arg(arp, unsigned int);


             }      //如果设置了'l',标志,则将数据转换为长整形。从参数中取出来。


             /* Put numeral string */  //下面是将数字转换为字符串。


             if (c == 'd') {


                    if (val & 0x80000000) {


                           val = 0 - val;


                           f |= 4;     //标志第二位表明这是个负数。


                    }      }


             i = sizeof(s) - 1; s = 0; //字符串最后一为以 '\0'结束。i指向尾端,往前扩展。


             do {          //同时处理十进制和十六进制。


                    c = (UCHAR)(val % r + '0');  //十进制时,1234/10,余数4+<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0,变成字符


                    if (c > '9') c += 7;  //十六进制,3A表示大写A,但实际的字符A0x41,中间差7.


                    s[--i] = c;      //前一位存储该字符


                    val /= r; //val变成123,也就是把尾端 一位去掉。


             } while (i && val);       //最多存储15位,要不然溢出。


             if (i && (f & 4)) s[--i] = '-';     //如果为负数,还要加上符号标志。


             w = sizeof(s) - 1 - w; //要求的宽度计算。8位宽,则填充从第7位开始。7-14,正好8位。


             while (i && i > w) s[--i] = (f & 1) ? '0' : ' ';//如果0填充置位填充0,否则填充空格。i退到0,或者i推导W都结束填充。


             cc = f_puts(&s, fil);


      }      va_end(arp);


      return (cc == EOF) ? cc : res;


}


 


把代码看了一遍,基本还是能看懂。


 


4、移植。


   1添加命令fstring该命令一个参数,是用户字符串。以附加的写入到指定的文件fstring.txt


2)实习方法


以写文件的方式,打开文件,然后指针移动到文件末尾。调用代码f_printf(&File输入字符串%s/r/n”,const char*argv[1])来写入文件。


3)代码实现


    res=f_open( &FileStr, "0:/doc/fstring.txt",FA_WRITE ); //


       res=f_lseek( &FileStr, FileStr.fsize );


 


       f_printf (&FileStr,"用户输入:%s\r\n",(char*)argv[1] );


       f_close (&FileStr );


功能比较简单,测试通过。


 


 


 


 

文章评论1条评论)

登录后参与讨论

用户1547738 2010-4-1 08:44

楼主再接再厉啊
相关推荐阅读
nthq2004 2010-05-08 20:04
USB自定义设备驱动02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  本来还想编写应用程序测试一下自定...
nthq2004 2010-05-07 21:35
USB自定义设备驱动01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、USB设备驱动入门1、学习目...
nthq2004 2010-05-04 21:01
智林开发板上实现自定义的USB HID设备
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、自定义HID设备的相关概念1...
nthq2004 2010-05-01 21:58
U盘例程在智林开发板上的移植
 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 一、移植前的准备工作1、有哪些操...
nthq2004 2010-04-30 19:19
U盘实现流程跟踪分析02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   二、追踪USB大容量设备的实现...
nthq2004 2010-04-27 21:51
U盘实现流程跟踪分析01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   一、追踪USB大容量设备的实现...
我要评论
1
4
关闭 站长推荐上一条 /2 下一条