6

私はmktempDを呼び出すのに苦労しています:

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) で終わる文字列に暗黙的に変換できることをどこかで読んだことがあると思います。

4

2 に答える 2

8

Adam の素晴らしい答えに加えて、 std.utf.toUTFzもあります。

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.toUTFzstd.string.toStringznull で終わる UTF-8、UTF-16、および UTF-32 文字列 (単なる UTF-8 とは対照的に) と任意のレベルの constness を生成するため、isのより有能ないとこです。immutable(char)*欠点は、戻り値の型を指定する必要があるため、必要な場合はより冗長になることです。

mktempただし、効率が問題になる場合は、渡される C 文字列をヒープに割り当てる必要がないという理由だけで、Adam のソリューションの方が優れている可能性があります。toUTFzただし、C 文字列をヒープに割り当てる効率のコストを気にしない場合 (ほとんどのプログラムは気にしない場合) は、toUTFz間違いなく優れています。特定のプログラムの要件によって異なります。

于 2013-11-30T20:49:59.340 に答える
8

この特定の問題の場合:

これは、mktemp が文字列に書き込む必要があるためです。mktemp(3) から:

テンプレートの最後の 6 文字は 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));
}

一般に、変更可能な文字列を作成するには、次の 2 つの方法のいずれかを使用できます。

toStringz入力データが可変かどうかは気にせず、常に不変を返します (明らかに...)。しかし、それを自分で行うのは簡単です:

auto c_str = ("foo".dup ~ "\0").ptr;

それがあなたのやり方です。

string name = "alphaXXXXXX"; // last six X's are required by mktemp
auto tmp = mktemp((name.dup ~ "\0").ptr);
于 2013-11-30T16:05:11.057 に答える