2015-08-26 9 views
7

I D Sprache lerne (Ich weiß, C++ gut) ... Ich mag einige Windows-spezifische Dinge zu tun, so schrieb ich dies nur die API auszuprobieren:einen temporären Zeichen-Array in einen String in D Konvertieren

import core.sys.windows.windows; 
import std.stdio; 

string name() 
{ 
    char buffer[100]; 
    uint size = 100; 

    GetComputerNameA(&buffer[0], &size); 

    return buffer; 
} 

void main() 
{ 
    writeln(name()); 
} 

ich in meiner return-Anweisung:

test.d(11): Error: cannot implicitly convert expression (buffer) of type char[100] to string 

Ok, in C++, es würde den Konstruktor aufrufen, um einen String zu machen. Es sagt implizit aus, dass wir es mit einem C-Style-Cast umsetzen können: return (string)buffer;.

test.d(11): Error: C style cast illegal, use cast(string)buffer 

Ah ok, ich erinnere mich, andere Syntax.

return cast(string)buffer; 

Jetzt kompiliert es, aber ich bekomme nur Müll.

Ich nehme an, dass ist, weil es einen Zeiger in der Zeichenfolge in den temporären Puffer speichert. Ich möchte das nicht machen, ich möchte die Charaktere in eine Zeichenfolge kopieren, aber ärgerlich finde ich nicht, wie ich das machen soll?

So Fragen:

  1. Wie kann ich eine tatsächliche Zeichenfolge aus einem char-Array erstellen, die Speicher richtig zuordnet? (Kopiert die Zeichen)

  2. Das Zuweisen eines Puffers mit einer zufälligen Größe wie dieser und Konvertieren in eine Zeichenfolge scheint hässlich zu sein. Gibt es einen geeigneten Weg, dies in D zu tun? (Ich spreche über die allgemeine Frage, nicht speziell diese API nur für den Fall, dass es eine andere API gibt, um den Computernamen zu erhalten).

  3. Wenn eine dieser Fragen in einem Handbuch beantwortet wird, wo sollte ich nach Details suchen?

Vielen Dank für jede Hilfe und Beratung.

+0

können Sie versuchen, den tatsächlichen Wert von 'buffer' zu überprüfen, bevor es umgesetzt ist, weil Die Konvertierung sollte nicht fehlschlagen. – Bauss

+0

Die Umwandlung funktioniert ... wenn ich es in der Funktion ... drucke, scheitert es, wenn ich einen String zurückgebe, vermutlich weil es sich immer noch auf den temporären Puffer bezieht. – jcoder

+1

@Bauss, nein, sollte es nicht. Tatsächlich bricht 2.068 die Kompilierung mit folgendem Fehler ab: "Fehler: Verweis auf lokalen Variablenpuffer". – sigod

Antwort

7

Ich glaube, Sie brauchen:

string name() 
{ 
    char buffer[100]; 
    uint size = 100; 

    GetComputerNameA(buffer.ptr, &size); 

    return buffer[0 .. size].idup; 
} 
+1

Das scheint elegent – jcoder

+1

Aber es ist immer noch ignorieren ERROR_BUFFER_OVERFLOW & GetLastError. Der korrekte Code sollte überprüfen, dass 'size' kleiner ist als buffer.length, und anderen neuen Puffer zuweist, sonst – sibnick

+0

Ja, natürlich war meine ursprüngliche Probe nur die kürzeste Probe, die ich schreiben könnte, um meine Frage zu demonstrieren. Es soll nicht vollständig sein. – jcoder

5

buffer.idup der normale Weg ist eine unveränderliche Kopie zu erhalten. Für diesen Fall, da Sie eine dynamisch große string (und erinnern Sie sich, dass string ist eigentlich nur Kurzschrift für immutable(char)[]) möchten, möchten Sie buffer[0..size].idup, mit D's Array Slicing.

Weitere Informationen finden Sie unter http://dlang.org/arrays.html.

(Dies ist ein bisschen wie ein nitpick, aber Sie können buffer.ptr statt &buffer[0], vor allem aus Gründen der Lesbarkeit halber verwendet werden soll.)

+0

Ausgezeichneter Dank, das funktioniert. Ok die Information ist jetzt klar. Es kann schwierig sein zu wissen, worauf Sie in der Dokumentation achten sollten, wenn Sie neu in einer Sprache sind. Und danke für den Nitpick! Das ist genau die Art von Rat, die ich brauche, wenn ich neu bei D bin :) – jcoder

Verwandte Themen