String 使用C样式字符串调用C函数

String 使用C样式字符串调用C函数,string,d,cstring,null-terminated,String,D,Cstring,Null Terminated,我很难在D中调用mktemp: import core.sys.posix.stdlib; import std.string: toStringz; auto name = "alpha"; auto tmp = mktemp(name.toStringz); 但我不知道如何使用它,所以DMD抱怨: /home/per/Work/justd/fs.d(1042): Error: function core.sys.posix.stdlib.mktemp (char*) is not call

我很难在D中调用
mktemp

import core.sys.posix.stdlib;
import std.string: toStringz;
auto name = "alpha";
auto tmp = mktemp(name.toStringz);
但我不知道如何使用它,所以DMD抱怨:

/home/per/Work/justd/fs.d(1042): Error: function core.sys.posix.stdlib.mktemp (char*) is not callable using argument types (immutable(char)*)
如何创建可变的以零结尾的C样式字符串


我想我在某个地方读到过字符串文本(
const
immutable
)可以隐式转换为以零(null)结尾的字符串。

对于此特定问题:

这是因为mktemp需要写入字符串。从mktemp(3)开始:

模板的最后六个字符必须是XXXXXX,并用使文件名唯一的字符串替换。由于模板将被修改,所以模板不能是字符串常量,而应声明为字符数组

因此,这里要做的是使用char[]而不是字符串。我同意:

import std.stdio;

void main() {
    import core.sys.posix.stdlib;

    // we'll use a little mutable buffer defined right here
    char[255] tempBuffer;
    string name = "alphaXXXXXX"; // last six X's are required by mktemp
    tempBuffer[0 .. name.length] = name[]; // copy the name into the mutable buffer
    tempBuffer[name.length] = 0; // make sure it is zero terminated yourself

    auto tmp = mktemp(tempBuffer.ptr);
    import std.conv;
    writeln(to!string(tmp));
}
一般来说,创建可变字符串可以通过两种方式之一完成:一种是使用.dup文件,另一种是像上面一样使用堆栈缓冲区

toStringz
不关心输入数据是否可变,它总是返回不可变的(显然…)。但自己动手做很容易:

auto c_str = ("foo".dup ~ "\0").ptr;
这就是你要做的,.dup制作了一个可变的拷贝,并且自己附加零终止符确保它在那里

string name = "alphaXXXXXX"; // last six X's are required by mktemp
auto tmp = mktemp((name.dup ~ "\0").ptr);
除此之外,还有,在这种情况下你可以

void main()
{
    import core.sys.posix.stdlib;
    import std.conv, std.stdio, std.utf;

    auto name = toUTFz!(char*)("alphaXXXXXX");
    auto tmp = mktemp(name);
    writeln(to!string(tmp));
}
std.utf.toUTFz
std.string.toStringz
的更强大的近亲,因为它将生成以null结尾的utf-8、utf-16和utf-32字符串(而不仅仅是utf-8)以及任何级别的常量。缺点是,对于只希望
不可变(char)*
的情况,它更为冗长,因为必须指定返回类型

然而,如果效率是个问题,Adam的解决方案可能会更好,因为它避免了分配传递给堆上
mktemp
的C字符串<但是code>toUTFz更短,因此如果您不关心在堆上分配C字符串的效率成本(大多数程序可能不会),那么
toUTFz
可以说更好。这取决于您的特定计划的要求