2007-05-18
.Net/Java 风格格式化字符串
关键字: Dotmars D基础类库的东西看起来容易做起来难,今天花时间实现了一点点 .Net 风格的字符串格式化函数,贴出来娱乐一下。
注意:目前仅支持占位符索引号而已...
- import std.stdio;
- import std.string;
- import std.conv;
- alias void delegate(char c) Sink;
- alias void* Argument;
- const size_t MaxArguments = 16;
- void format(char[] fmt, Sink sink, Argument argPtr, TypeInfo[] argtis)
- {
- assert(argtis.length <= MaxArguments, "format: Too many arguments");
- Argument[MaxArguments] args = void;
- //填充参数指针
- foreach (size_t i, ti; argtis)
- {
- args[i] = argPtr;
- //来自于 stdarg.d,避免不同CPU建构中堆栈结构差异
- argPtr += (ti.tsize + int.sizeof - 1) & ~ (int.sizeof - 1);
- }
- doFormat(fmt, sink, args, argtis);
- }
- void format(char[] fmt, Sink sink, ...)
- {
- format(fmt, sink, _argptr, _arguments);
- }
- size_t skipSpaces(char[] str)
- {
- size_t i;
- for(i = 0; i < str.length; i++)
- {
- if(str[i] != ' ')return i;
- }
- return i;
- }
- uint extractNumber(char[] str)
- {
- size_t len = 0;
- foreach(char c; str)
- {
- if(c >= '0' && c <= '9') len++;
- else break;
- }
- if(len == 0)
- throw new Exception("Format: syntax error");
- return toUint(str[0 .. len]);
- }
- size_t findRightBrach(char[] str)
- {
- foreach(size_t i, char c; str)
- {
- if(c == '}')
- return i;
- }
- //大括号不匹配
- throw new Exception("Format: Syntax error");
- }
- void doFormat(char[] fmt, Sink sink, Argument[] args, TypeInfo[] ti)
- {
- for(size_t i = 0; i < fmt.length;)
- {
- //跳过非占位符
- for(; i < fmt.length && fmt[i] != '{'; i++)
- sink(fmt[i]);
- if(i >= fmt.length)break;
- // "{{" 转义,输出 '{' 即可
- if(i < fmt.length - 1 && fmt[i + 1] == '{')
- {
- i += 2;
- sink('{');
- continue;
- }
- size_t beginBrach = i;
- size_t endBrach = i + findRightBrach(fmt[i .. $]);
- // parsing the format string
- doParse(fmt[beginBrach + 1 .. endBrach], sink, args, ti);
- i = endBrach + 1;
- }
- }
- void doParse(char[] fmt, Sink sink, Argument[] args, TypeInfo[] ti)
- {
- size_t i = 0;
- i += skipSpaces(fmt);
- //提取索引号
- uint index = extractNumber(fmt);
- ////TODO: 其他类型支持在此处添加
- int *iptr = cast(int*)args[index];
- foreach(char c; std.string.toString(*iptr))
- sink(c);
- }
- void print(char[] fmt, ...)
- {
- void sink(char c)
- {
- writef(c);
- }
- format(fmt, &sink, _argptr, _arguments);
- }
- void main()
- {
- print("Hello {0} {2} brach{{}}brach {1} Dotmars\n", 111, 2222, 333);
- }
发表评论
- 浏览: 105140 次
- 性别:

- 来自: 昆明

- 详细资料
搜索本博客
我的相册
Screenshot
共 1 张
共 1 张
最近加入圈子
最新评论
-
出色的开源项目管理软件— ...
我也是前几天刚刚从trac换到redmine,感觉好多了,trac有的redmi ...
-- by danielking -
转贴:鲁迅未收入全集的文 ...
借问酒家何处有,牧童遥指杏花村
-- by hqs7636 -
Range Coding 的 D 实现
引用oldrev 2008-01-12LZMA SDK 只是一个 LZMA 算法 ...
-- by oldrev -
D 静态数组初始化大bug
看看日期好伐?
-- by oldrev -
D新闻组里的天才代码
没看过产生的汇编代码,测试了是可行的。如果用宏来实现就完美了
-- by oldrev






评论排行榜