डी

2015-08-26 4 views
7

मैं डी भाषा (मैं सी ++ में अच्छी तरह से जानते हैं) ... मैं कुछ Windows विशिष्ट सामान करना चाहता हूँ सीख रहा हूँ में एक स्ट्रिंग के लिए एक अस्थायी चरित्र सरणी परिवर्तित तो मैं यह लिखा सिर्फ एपीआई आज़माने के लिए:डी

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

मैं अपना निवेश बयान में मिलती है:

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

ठीक है, C++ यह निर्माता एक स्ट्रिंग बनाने के लिए कहेंगे। यह अंतर्निहित कहता है इसलिए इसे सी स्टाइल कास्ट के साथ डालने दें: return (string)buffer;

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

आह ठीक है, मुझे याद है, अलग वाक्यविन्यास।

return cast(string)buffer; 

अब यह संकलित करता है लेकिन मुझे कचरा मिलता है।

मुझे लगता है कि ऐसा इसलिए है क्योंकि यह स्ट्रिंग में अस्थायी बफर को पॉइंटर संग्रहीत कर रहा है। मैं यह नहीं करना चाहता, मैं पात्रों को एक स्ट्रिंग में कॉपी करना चाहता हूं लेकिन परेशान है कि मुझे यह नहीं लगता कि यह कैसे करना है?

तो सवाल:

  1. मैं एक चार सरणी कि भंडारण ठीक से आवंटित से एक वास्तविक स्ट्रिंग कैसे निर्माण करते हैं? (पात्रों की प्रतिलिपि)

  2. इस तरह के एक यादृच्छिक आकार के बफर को आवंटित करना और स्ट्रिंग में कनवर्ट करना बदसूरत लगता है। क्या डी में ऐसा करने का कोई उचित तरीका है? (मैं सामान्य प्रश्न के बारे में बात कर रहा हूं, विशेष रूप से यह एपीआई नहीं, अगर कंप्यूटर नाम प्राप्त करने के लिए कोई और एपीआई है)।

  3. यदि इनमें से किसी एक को मैनुअल में उत्तर दिया गया है तो मुझे विवरण ढूंढने के लिए कहां देखना चाहिए?

किसी भी मदद और सलाह के लिए धन्यवाद।

+0

आप, 'buffer' के वास्तविक मूल्य की जाँच करने से पहले इसे बदला न गया हो की कोशिश कर सकते हैं क्योंकि रूपांतरण विफल नहीं होना चाहिए। – Bauss

+0

रूपांतरण काम करता है ... अगर मैं इसे फ़ंक्शन में प्रिंट करता हूं ... यदि मैं स्ट्रिंग वापस करता हूं तो यह विफल रहता है, संभवतः क्योंकि यह अभी भी अस्थायी बफर को संदर्भित करता है। – jcoder

+1

@ बास, नहीं, यह नहीं होना चाहिए। वास्तव में 2.068 aborts संकलन के साथ: 'त्रुटि: स्थानीय चर बफर के संदर्भ से बचने। – sigod

उत्तर

7

मुझे लगता है कि आप की जरूरत:

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

    GetComputerNameA(buffer.ptr, &size); 

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

स्वीकार करना न भूलें जो कि – jcoder

+1

सुंदर लगता है लेकिन यह अभी भी ERROR_BUFFER_OVERFLOW और GetLastError को अनदेखा कर रहा है। सही कोड को जांचना चाहिए कि 'आकार' बफर। लम्बाई से कम है, और नए बड़े बफर आवंटित करता है अन्यथा – sibnick

+0

हां, मेरा मूल नमूना केवल सबसे छोटा नमूना था जिसे मैं अपने प्रश्न का प्रदर्शन करने के लिए लिख सकता था। इसका पूरा इरादा नहीं है। – jcoder

5

buffer.idup अपरिवर्तनीय प्रतिलिपि प्राप्त करने मानक तरीका है। इस मामले के लिए, चूंकि आप गतिशील रूप से आकार string (और याद रखें कि string वास्तव में immutable(char)[] के लिए केवल शॉर्टेंड है), आप buffer[0..size].idup चाहते हैं, डी एस सर स्लाइसिंग का उपयोग कर।

अधिक जानकारी के लिए http://dlang.org/arrays.html देखें।

(यह एक nitpick का एक सा है, लेकिन आप &buffer[0] के बजाय buffer.ptr उपयोग करने के लिए, ज्यादातर पठनीयता के लिये कर सकते हैं।)

+0

उत्कृष्ट धन्यवाद, यह काम करता है। ठीक है अब जानकारी स्पष्ट है। यह जानना मुश्किल हो सकता है कि जब आप किसी भाषा में नए होते हैं तो दस्तावेज़ में क्या देखना है। और नाइटपिक के लिए धन्यवाद! जब मैं डी के लिए नया हूं तो मुझे बिल्कुल यही सलाह चाहिए :) – jcoder