d的printf元编程,适用于betterC
使用:
int i;
dprintf!"hello %s %s %s %s betty\n"(3, 4.0, &i, "abc".ptr);
重写为:
printf("hello %d %g %p %s betty\n", 3, 4.0, &i, "abc".ptr);
import core.stdc.stdio : printf;
template Seq(A ...) { alias Seq = A; }
int dprintf(string f, A ...)(A args)
{
enum Fmts = Formats!(A);
enum string s = formatString(f, Fmts);
__gshared const(char)* s2 = s.ptr;
return printf(Seq!(s2, args[0..2], args[2..4]));
}
template Formats(T ...)
{
static if (T.length == 0)
enum Formats = [ ];
else static if (T.length == 1)
enum Formats = [Spec!(T[0])];
else
enum Formats = [Spec!(T[0])] ~ Formats!(T[1 .. T.length]);
}
template Spec(T : byte) { enum Spec = "%d"; }
template Spec(T : short) { enum Spec = "%d"; }
template Spec(T : int) { enum Spec = "%d"; }
template Spec(T : long) { enum Spec = "%lld"; }
template Spec(T : ubyte) { enum Spec = "%u"; }
template Spec(T : ushort) { enum Spec = "%u"; }
template Spec(T : uint) { enum Spec = "%u"; }
template Spec(T : ulong) { enum Spec = "%llu"; }
template Spec(T : float) { enum Spec = "%g"; }
template Spec(T : double) { enum Spec = "%g"; }
template Spec(T : real) { enum Spec = "%Lg"; }
template Spec(T : char) { enum Spec = "%c"; }
template Spec(T : wchar) { enum Spec = "%c"; }
template Spec(T : dchar) { enum Spec = "%c"; }
template Spec(T : immutable(char)*) { enum Spec = "%s"; }
template Spec(T : const(char)*) { enum Spec = "%s"; }
template Spec(T : T*) { enum Spec = "%p"; }
/******************************************
* Replace %s format specifiers in f with corresponding specifiers in A[].
* Other format specifiers are left as is.
* Number of format specifiers must match A.length.
* Params:
* f = printf format string
* A = replacement format specifiers
* Returns:
* replacement printf format string
*/
string formatString(string f, string[] A ...)
{
string r;
size_t i;
size_t ai;
while (i < f.length)
{
if (f[i] != '%' || i + 1 == f.length)
{
r ~= f[i];
++i;
continue;
}
char c = f[i + 1];
if (c == '%')
{
r ~= "%%";
i += 2;
continue;
}
assert(ai < A.length, "not enough arguments");
string fmt = A[ai];
++ai;
if (c == 's')
{
r ~= fmt;
i += 2;
continue;
}
r ~= '%';
++i;
continue;
}
assert(ai == A.length, "not enough formats");
return r;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现