2015-08-26 11 views
7

sto imparando la lingua D (lo so C++ bene) ... voglio fare alcune cose specifiche di Windows così ho scritto questo solo per provare l'API:Conversione di un array di carattere temporaneo ad una stringa in D

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()); 
} 

ottengo nella mia dichiarazione di ritorno:

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

Ok, in C++ sarebbe chiamare il costruttore di fare una stringa. Dice implicito, quindi lasciamolo col cast di stile C: return (string)buffer;.

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

Ah ok, ricordo, sintassi diversa.

return cast(string)buffer; 

Ora compila ma ottengo solo rifiuti.

Suppongo che sia perché memorizza un puntatore nella stringa nel buffer temporaneo. Non voglio farlo, voglio copiare i personaggi in una stringa, ma fastidiosamente non riesco a trovare come farlo?

quindi le domande:

  1. Come faccio a costruire una stringa effettiva da un array di caratteri che alloca memoria correttamente? (Copia i caratteri)

  2. Assegnare un buffer di una dimensione casuale come questa e convertirlo in una stringa sembra brutto. C'è un modo corretto per farlo in D? (Sto parlando della domanda generale, non specificamente di questa API nel caso in cui ci sia un'altra API per ottenere il nome del computer).

  3. Se a qualcuno di questi viene risposto in un manuale dove dovrei cercare di trovare i dettagli?

Grazie per qualsiasi aiuto e consiglio.

+0

Puoi provare a controllare il valore effettivo del 'buffer' prima che sia convertito, perché la conversione non dovrebbe fallire. – Bauss

+0

La conversione funziona ... se la stampo nella funzione ... fallisce se restituisco una stringa, presumibilmente perché si riferisce ancora al buffer temporaneo. – jcoder

+1

@ Bauss, no, non dovrebbe. In effetti 2.068 interrompe la compilazione con: 'Errore: richiamo del riferimento al buffer delle variabili locali'. – sigod

risposta

7

Penso che avete bisogno:

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

    GetComputerNameA(buffer.ptr, &size); 

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

Che sembra elegante – jcoder

+1

Ma si ignora ancora ERROR_BUFFER_OVERFLOW e GetLastError. Il codice corretto dovrebbe verificare che 'size' sia inferiore al buffer.length e alloca il nuovo buffer più grande altrimenti – sibnick

+0

Sì, naturalmente, il mio campione originale era solo il campione più corto che potessi scrivere per dimostrare la mia domanda. Non è destinato ad essere completo. – jcoder

5

buffer.idup è il modo standard per ottenere una copia immutabile. Per questo caso, dal momento che si desidera una dimensione dinamica string (e si ricordi che) si tratta semplicemente di una scorciatoia per immutable(char)[], si utilizza buffer[0..size].idup, utilizzando l'affinamento di array di D.

Vedere http://dlang.org/arrays.html per ulteriori informazioni.

(Questo è un po 'un nitpick, ma si consiglia di utilizzare buffer.ptr invece di &buffer[0], principalmente per la propria leggibilità.)

+0

Eccellente grazie, Funziona. Ok, l'informazione è chiara ora. Può essere difficile sapere cosa cercare nella documentazione quando sei nuovo in una lingua. E grazie per il nitpick! Questo è esattamente il tipo di consiglio di cui ho bisogno quando sono nuovo a D :) – jcoder

Problemi correlati