原文 通過傳遞
InputRange
而不是
const(char)
給
toCStringThen
來提供無配置設定
0終止串
.
//version=AllowMalloc;//.1
auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) {
const len = src.walkLength;
char[512] small = void;
version(AllowMalloc) {
import dmd.common.string : SmallBuffer;
auto sb = SmallBuffer!char(len + 1, small[]);
scope ptr = sb[];
} else {
enforce(len < small.length, format!"C串溢出"(len, small.length));
scope ptr = small[];
}
size_t i = 0;
foreach (char c; src)
ptr[i++] = c;
ptr[len] = '\0';
return dg(ptr);
}
void main() {
string path = "include/";
string name = "file";
string ext = ".ext";
auto filename = chain(path, name, ext);
filename.writeln;
filename.byChar.toCStringThen!(
(str) => printf("printf: {%s}\n", str.ptr)
);
}
可能需要清理
符類型
,且如果允許
配置設定
,還需要
疊代兩次
,而
walkLength/chain()
的區間函數不是
不抛
的.
//version=AllowMalloc;
auto toCStringThen(alias dg, Range)(Range src) /*nothrow*/ if (isInputRange!Range && !isInfinite!Range) {
char[10] small = void;
size_t i = 0;
while(!src.empty && i < small.length) {
small[i++] = src.front;
src.popFront;
}
if(i == small.length) {
version(AllowMalloc) {
import std.container.array;
Array!char large = small[];
large ~= src;
large ~= '\0';
return dg(large.data);
} else {
throw new Exception(
"C串緩沖溢出(%s >= %s)"
.format(i+src.walkLength, small.length-1)
);
}
} else {
small[i] = '\0';
return dg(small[0..i]);
}
}