`
oldrev
  • 浏览: 229899 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
社区版块
存档分类
最新评论

.Net/Java 风格格式化字符串

阅读更多

基础类库的东西看起来容易做起来难,今天花时间实现了一点点 .Net 风格的字符串格式化函数,贴出来娱乐一下。

注意:目前仅支持占位符索引号而已...

  1. import std.stdio;
  2. import std.string;
  3. import std.conv;
  4. alias void delegate(char c) Sink;
  5. alias void* Argument;
  6. const size_t MaxArguments = 16;
  7. void format(char[] fmt, Sink sink, Argument argPtr, TypeInfo[] argtis)
  8. {
  9. assert(argtis.length <= MaxArguments, "format: Too many arguments");
  10. Argument[MaxArguments] args = void;
  11. //填充参数指针
  12. foreach (size_t i, ti; argtis)
  13. {
  14. args[i] = argPtr;
  15. //来自于 stdarg.d,避免不同CPU建构中堆栈结构差异
  16. argPtr += (ti.tsize + int.sizeof - 1) & ~ (int.sizeof - 1);
  17. }
  18. doFormat(fmt, sink, args, argtis);
  19. }
  20. void format(char[] fmt, Sink sink, ...)
  21. {
  22. format(fmt, sink, _argptr, _arguments);
  23. }
  24. size_t skipSpaces(char[] str)
  25. {
  26. size_t i;
  27. for(i = 0; i < str.length; i++)
  28. {
  29. if(str[i] != ' ')return i;
  30. }
  31. return i;
  32. }
  33. uint extractNumber(char[] str)
  34. {
  35. size_t len = 0;
  36. foreach(char c; str)
  37. {
  38. if(c >= '0' && c <= '9') len++;
  39. else break;
  40. }
  41. if(len == 0)
  42. throw new Exception("Format: syntax error");
  43. return toUint(str[0 .. len]);
  44. }
  45. size_t findRightBrach(char[] str)
  46. {
  47. foreach(size_t i, char c; str)
  48. {
  49. if(c == '}')
  50. return i;
  51. }
  52. //大括号不匹配
  53. throw new Exception("Format: Syntax error");
  54. }
  55. void doFormat(char[] fmt, Sink sink, Argument[] args, TypeInfo[] ti)
  56. {
  57. for(size_t i = 0; i < fmt.length;)
  58. {
  59. //跳过非占位符
  60. for(; i < fmt.length && fmt[i] != '{'; i++)
  61. sink(fmt[i]);
  62. if(i >= fmt.length)break;
  63. // "{{" 转义,输出 '{' 即可
  64. if(i < fmt.length - 1 && fmt[i + 1] == '{')
  65. {
  66. i += 2;
  67. sink('{');
  68. continue;
  69. }
  70. size_t beginBrach = i;
  71. size_t endBrach = i + findRightBrach(fmt[i .. $]);
  72. // parsing the format string
  73. doParse(fmt[beginBrach + 1 .. endBrach], sink, args, ti);
  74. i = endBrach + 1;
  75. }
  76. }
  77. void doParse(char[] fmt, Sink sink, Argument[] args, TypeInfo[] ti)
  78. {
  79. size_t i = 0;
  80. i += skipSpaces(fmt);
  81. //提取索引号
  82. uint index = extractNumber(fmt);
  83. ////TODO: 其他类型支持在此处添加
  84. int *iptr = cast(int*)args[index];
  85. foreach(char c; std.string.toString(*iptr))
  86. sink(c);
  87. }
  88. void print(char[] fmt, ...)
  89. {
  90. void sink(char c)
  91. {
  92. writef(c);
  93. }
  94. format(fmt, &sink, _argptr, _arguments);
  95. }
  96. void main()
  97. {
  98. print("Hello {0} {2} brach{{}}brach {1} Dotmars\n", 111, 2222, 333);
  99. }

分享到:
评论
1 楼 DavidL 2007-05-20  
呵呵,是我的话抄袭Tango的就算了

相关推荐

    java常用类解析及示例及一些工具类源代码

    主要讲解了System类、Object类、Arrays类、Cloneable接口、IO系统输入输出类及装饰类、IO系统文本读写工具类、IO系统二进制读写工具类、对象序列化工具类、File类及文件搜索工具类、java异常机制及自定义异常类、...

    Postman使用详解(文档+视频+postman请求导出文件+后台java工程演示资源).rar

    详细介绍postman发送{}、[] 格式数据,后端10多种接收参数方式包括字符串、list、map等格式、详细介绍postman发送请求Params、form-data、raw、x-www-form-urlencoded的区别)、模拟跨域、设置断言、Postman模拟高...

    asp.net知识库

    .NET 2.0中的字符串比较 小试ASP.NET 2.0的兼容性 为 asp.net 2.0 的菜单控件增加 target 属性 ASP.NET 2.0 的内部变化 常见的 ASP.NET 2.0 转换问题和解决方案 Asp.Net2.0无刷新客户端回调 体验.net 2.0 的优雅(1...

    C# To JAVA Converter v17.10.6

    许多转换和格式化选项 将C#代理和lambdas转换为Java接口和lambdas 使用Java泛型转换C#ref参数 当代码中定义事件委托时转换C#事件,或者是System.Action或System.Func代理之一 将所有类型的数组从C#转换成Java ...

    easypoi 模板导出图片不显示,循环指令中合并单元格格式错乱问题解决

    (1)模板导出图片不显示(实际上导出来了只是最小化显示了) (2)fe循环指令存在而合并单元格的时候格式错乱问题 (3)fe存在一对多关系的时候格式错乱问题 不想下载的可以参考博文 ,代码是一样的 ...

    spring.net中文手册在线版

    16.1.3.管理连接字符串 第十七章. 使用ADO.NET进行数据访问 17.1.简介 17.2.动机 17.3.Provider抽象 17.3.1.创建IDbProvider类型的实例 17.4.命名空间 17.5.数据访问的方式 17.6.AdoTemplate简介 17.6.1.执行回调 ...

    JAVA_API1.6文档(中文)

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    java源码包---java 源码 大量 实例

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    JAVA上百实例源码以及开源项目

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    集成安卓主流优秀第三方组件框架.zip

    字符串操作工具类(ToolString.java),生成UUID、非空非NULL逻辑判断、生成MD5等常用共通方法 数据操作工具类(ToolData.java),自动递归获取表单数据封装成Map、本地数据分页共通方法等 图片操作工具类...

    JAVA上百实例源码以及开源项目源代码

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    Spring.net框架

    SayHello类持有一个对EnHelloGenerator的引用,并负责将生成出来的问候字符串打印出来。 using System; namespace IocInCSharp { public class SayHello { private EnHelloGenerator _helloGen; public ...

    Java 1.6 API 中文 New

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...

    java源码包4

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    java源码包3

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    java源码包2

     设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节  通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到...

    java api最新7.0

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...

    JavaAPI1.6中文chm文档 part1

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    Visual C++ 2005入门经典--源代码及课后练习答案

    2.9.3 C++/CLI特有的功能——格式化输出 92 2.9.4 C++/CLI的键盘输入 94 2.9.5 使用safe_cast 95 2.9.6 C++/CLI枚举 96 2.10 小结 98 2.11 练习题 100 第3章 判断和循环 101 3.1 比较数据值 101 ...

Global site tag (gtag.js) - Google Analytics