exercise.6-4 in <The C programming Language> ,page125
exercise.7-2.<The C Programming Language>.Page 136

exercise.7-3.<The C programming Language>.Page136

TLHL28 posted @ Sun, 03 Aug 2008 02:35:09 +0800 in C语言 with tags C语言 , 1545 readers

 编的时候变量名字随便弄,感觉好乱。后来重新整理了下,可能不太规范(包括英文的命名),这过程花时间阿......。

下次要想好再弄了......。还有,本练习和我找到的答案差好远,答案实现各种格式的输出。我却去实现最小字段啊,精度阿,向左对齐的功能......难道是我把"更多功能"理解错了??

 

  1. /*改写minprintf函数, 使它能完成printf函数的更多功能
  2. *(没走 “printf("%.*s",max, s)” 这种途径,所以在打印
  3. * double型的时候精度只正能到小数点后13位)
  4. *exercise.7-3.<The C programming Language>.Page136
  5. *test_Usage: ./program_name
  6. * finish time : 08/08/02;
  7. * */
  8. #include <stdio.h>
  9. #include <stdarg.h>
  10. #include <ctype.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. /*  minprintf函数: 带有可变参数表的简化的printf函数 */
  15. void minprintf(char *fmt,...);
  16.  
  17. /*  getlength函数: 获取最小字段宽度或精度*/
  18. int getlength();
  19.  
  20. /*  指定输出方式: 本函数参数1为待输出参数(转为字符串),
  21. *  参数2为待处理方式(本程序只分为"double","string"两种,
  22. *  其中,对double类要进行小数点的精度处理。)
  23. *  */
  24. void type_space(char *,char *);
  25.  
  26. int global_print_type;      //主要用于存放打印格式如: d,s,f
  27. char *global_p_fmt; //指向转换格式format说明的指针。
  28.  
  29. int global_min_width;      /*用于指定最小的字段宽度*/
  30. int global_precision = 0;       /*  全局变量,精度  */
  31. int layout_length = 0;    /*  同min_width,当有‘-’时,记录对齐长度    */
  32. int words_length = 0;      /*  记录要打印参数(s,f)的长度    */ 
  33. int getdot = 0, getlay = 0;     /*  获取打印格式的记录
  34.                                     getdot表示开始获取精度,getlay获取对其长度*/
  35.  
  36. /* 测试 */
  37. int main()
  38. {
  39.     char *string = "for test!";
  40.     int intt = 555;
  41.     double doubt = 666.22;
  42.     minprintf("%d, %f, %10.5s\n",intt, doubt, string);
  43.  
  44.     minprintf("\n:%-10.3s:\n",string);
  45.     printf(":%-10.3s:\n",string);
  46.  
  47.     minprintf("\n:%-15s:\n",string);
  48.     printf(":%-15s:\n",string);
  49.  
  50.     printf(":%-7f:\n",doubt);
  51.     minprintf(":%-7f:\n",doubt);
  52.  
  53.     printf("\n:%-15.7f:\n",doubt);
  54.     minprintf(":%-15.7f:\n",doubt);
  55.  
  56.     printf("\n:%.10f:\n",doubt);
  57.     minprintf(":%.10f:\n",doubt);
  58.  
  59.  
  60.     return 0;
  61. }
  62.  
  63.  
  64. void minprintf(char *fmt,...)
  65. {
  66.     va_list ap;     /*   依次指向每一个无名参数  */
  67.     char *sval;
  68.     int ival;
  69.     double dval;
  70.     char double_str[100];   /*将double转换成string后临时存放位置*/
  71.  
  72.     va_start(ap, fmt); /*   将ap指向第一个无名参数 */
  73.     for (global_p_fmt = fmt; *global_p_fmt; global_p_fmt++) {
  74.         if (*global_p_fmt != '%') {
  75.             putchar(*global_p_fmt);
  76.             continue;
  77.         }
  78.         if ((global_print_type = *++global_p_fmt) == '-') {
  79.             getlay = 1;
  80.             if (isdigit(global_print_type = *++global_p_fmt))
  81.                 layout_length = getlength();
  82.         } else if (isdigit(global_print_type)) {
  83.             global_min_width = getlength();
  84.         }
  85.         if (global_print_type == '.') {
  86.             getdot = 1;
  87.             if (isdigit(global_print_type = *++global_p_fmt))
  88.                 global_precision = getlength();
  89.         }
  90.         switch (global_print_type) {
  91.             case 'd':
  92.                 ival = va_arg(ap, int);
  93.                 printf("%d", ival);
  94.                 break;
  95.             case 'f':
  96.                 dval = va_arg(ap, double);
  97.                 sprintf(double_str,"%.13f",dval);
  98.                 type_space(double_str, "double");
  99.                 break;
  100.             case 's':
  101.                 sval = va_arg(ap, char *);
  102.                 type_space(sval, "string");
  103.                 break;
  104.             default:
  105.                 putchar(*global_p_fmt);
  106.                 break;
  107.         }
  108.     }
  109.     va_end(ap);     /*   结束时的清理工作    */
  110. }
  111.  
  112. int getlength()
  113. {
  114.     char slength[10];
  115.     int i;
  116.  
  117.     slength[0] = global_print_type;
  118.     i = 0;
  119.     while (isdigit(global_print_type = *++global_p_fmt))
  120.         slength[++i] = global_print_type;
  121.     slength[++i] = '\0';
  122.     return atoi(slength);
  123. }
  124.  
  125. void type_space(char *sval,char *global_print_type)
  126. {
  127.  
  128.     int default_precision = 0/*  double类型默认的精度    */
  129.     int double_precision = 0;   /*  记录定义后的精度    */
  130.     int temp_double_precision;
  131.     int temp_global_precision;
  132.    
  133.     /*打印格式判断*/
  134.     int isdouble = strcmp(global_print_type, "double") == 0 ? 1 : 0;
  135.     int isstring = strcmp(global_print_type, "string") == 0 ? 1: 0;
  136.  
  137.     if (isdouble) {
  138.         default_precision = strcspn(sval,".") + 1 + 6;
  139.         if (getdot)
  140.             double_precision = global_precision + strcspn(sval,".") + 1;
  141.     }
  142.     if (isstring)
  143.         words_length = strlen(sval);
  144.     else if (isdouble) {
  145.         if (!getdot)
  146.             words_length = default_precision;
  147.         else if(global_precision > 6)
  148.             words_length = strcspn(sval,".") + 1 + global_precision;
  149.     }
  150.  
  151.     /*  打印参数不超过最小字段的时候填充适当的空格*/
  152.     if (words_length < global_min_width) {
  153.         if (getdot) {
  154.             if (isdouble)
  155.                 global_min_width -= double_precision;
  156.             else
  157.                 global_min_width -= global_precision;
  158.         } else
  159.             global_min_width -= words_length;
  160.         while (global_min_width-- > 0)
  161.             printf("T");
  162.     }
  163.  
  164.     temp_global_precision = global_precision;
  165.     temp_double_precision = double_precision;
  166.  
  167.     /*  打印参数    */
  168.     for (; *sval; sval++) {
  169.         if (getdot) {
  170.             if (isstring && !temp_global_precision--)
  171.                 break;
  172.             else if (isdouble && !temp_double_precision--)
  173.                 break;
  174.         } else if (isdouble)
  175.             if (!default_precision --)
  176.                 break;
  177.         putchar(*sval);
  178.     }
  179.  
  180.     /*  double参数小数位不超过定义精度的话补0      */
  181.     if (isdouble) {
  182.         temp_global_precision = global_precision;
  183.         while (*sval == '\0' && temp_global_precision-- > 6)
  184.             printf("0");
  185.     }
  186.  
  187.     /*  左对齐时,参数长度不够指定长度长时扑空格    */
  188.     if (getlay && words_length < layout_length) {
  189.         if (getdot) {
  190.             if (isdouble)
  191.                 layout_length -= double_precision;
  192.             else
  193.                 layout_length -= global_precision;
  194.         } else
  195.             layout_length -= words_length;
  196.         while (layout_length-- > 0)
  197.             printf("T");
  198.     }
  199.  
  200.     /* 重新初始化各个打印规则 */
  201.     global_min_width = 0;
  202.     global_precision = 0;
  203.     layout_length = 0;
  204.     words_length = 0;
  205.     getdot = 0, getlay = 0;
  206.  
  207. }

 


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter