2009-12-02 17 views
8

में कैरेक्टर स्ट्रिंग पाएं मेरे पास एक बाइनरी फ़ाइल है जिसे मैंने NSData ऑब्जेक्ट का उपयोग करके लोड किया है। क्या वर्णों के अनुक्रम का पता लगाने का कोई तरीका है, उदाहरण के लिए, 'abcd', उस बाइनरी डेटा के भीतर और संपूर्ण फ़ाइल को स्ट्रिंग में परिवर्तित किए बिना ऑफ़सेट लौटाएं? ऐसा लगता है कि यह एक साधारण जवाब होना चाहिए, लेकिन मुझे यकीन नहीं है कि यह कैसे करें। कोई विचार?बाइनरी डेटा

मैं इसे आईओएस 3 पर कर रहा हूं इसलिए मेरे पास -rangeOfData:options:range: उपलब्ध नहीं है।

मैं स्ट्रैस्ट्र का सुझाव देने के लिए इसे सोलह ओटो तक पुरस्कार देने जा रहा हूं। मैं चला गया और सी फंक्शन स्ट्रस्ट्र के लिए स्रोत कोड मिला और इसे एक निश्चित लंबाई बाइट सरणी पर काम करने के लिए फिर से लिखना - जो संयोग से चार सरणी से अलग है क्योंकि यह शून्य समाप्त नहीं हुआ है।

- (Byte*)offsetOfBytes:(Byte*)bytes inBuffer:(const Byte*)buffer ofLength:(int)len; 
{ 
    Byte *cp = bytes; 
    Byte *s1, *s2; 

    if (!*buffer) 
     return bytes; 

    int i = 0; 
    for (i=0; i < len; ++i) 
    { 
     s1 = cp; 
     s2 = (Byte*)buffer; 

     while (*s1 && *s2 && !(*s1-*s2)) 
      s1++, s2++; 

     if (!*s2) 
      return cp; 

     cp++; 
    } 

    return NULL; 
} 

यह बाइट्स की पहली घटना, बात मैं तलाश कर रहा हूँ, बफर में, बाइट सरणी बाइट्स शामिल करना चाहिए करने के लिए एक सूचक रिटर्न: यहाँ कोड मैं के साथ समाप्त हो गया है।

मैं इस तरह इसे कहते:

// data is the NSData object 
const Byte *bytes = [data bytes]; 
Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]]; 
+0

कोड जो आपने ऑफसेट के लिए पोस्ट किया है ओफबाइट्स: इनबफर: लम्बाई: यदि आपके डेटा में वास्तव में नल शामिल हो सकते हैं तो बहुत सारे मुद्दे होंगे (मूल स्ट्रस्ट्र() छोड़ दिया गया है)। कम से कम, आपको बाइट्स की लंबाई में गुजरने की आवश्यकता है, क्योंकि इस फ़ंक्शन को यह नहीं पता है कि यह कब तक होना चाहिए। –

+0

अरे। प्रतिक्रिया के लिए धन्यवाद। मैं लम्बाई में पैरामीटर के लिए लंबाई में गुजर रहा हूं: पैरामीटर, इसलिए मुझे यकीन नहीं है कि आपका क्या मतलब है। धन्यवाद। –

+0

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

उत्तर

14

बड़ा NSData में उन बाइट्स के लिए खोज rangeOfData:options:range: का उपयोग कर एक NSData वस्तु को अपने-स्ट्रिंग में कनवर्ट करें, और। सुनिश्चित करें कि स्ट्रिंग एन्कोडिंग मैच!

आईफोन पर, जहां यह उपलब्ध नहीं है, आपको इसे स्वयं करना पड़ सकता है। सी फ़ंक्शन strstr() आपको बफर के भीतर किसी पैटर्न की पहली घटना के लिए सूचक करेगा (जब तक न तो नल हो!), लेकिन सूचकांक नहीं। यहाँ एक समारोह है कि (है, लेकिन कोई वादा के बाद से मैं वास्तव में यह चल रहा प्रयास नहीं किया है ...) काम करना चाहिए:

- (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack 
{ 
    const void* needleBytes = [needle bytes]; 
    const void* haystackBytes = [haystack bytes]; 

    // walk the length of the buffer, looking for a byte that matches the start 
    // of the pattern; we can skip (|needle|-1) bytes at the end, since we can't 
    // have a match that's shorter than needle itself 
    for (NSUInteger i=0; i < [haystack length]-[needle length]+1; i++) 
    { 
     // walk needle's bytes while they still match the bytes of haystack 
     // starting at i; if we walk off the end of needle, we found a match 
     NSUInteger j=0; 
     while (j < [needle length] && needleBytes[j] == haystackBytes[i+j]) 
     { 
      j++; 
     } 
     if (j == [needle length]) 
     { 
      return i; 
     } 
    } 
    return NSNotFound; 
} 

यह हे (एनएम) है, जहां n है की तरह कुछ में चलता है बफर लंबाई, और मीटर सबस्ट्रिंग का आकार है। यह दो कारणों से NSData के साथ काम करने के लिए लिखा गया है: 1) यह आपके हाथ में प्रतीत होता है, और 2) वे ऑब्जेक्ट्स पहले से ही वास्तविक बाइट्स और बफर की लंबाई दोनों को समाहित करते हैं।

+1

मुझे यह उल्लेख करना चाहिए था कि मैं इसे आईफोन पर कर रहा हूं जिसमें श्रेणी नहीं है डेटा: विकल्प: सीमा: विधि। हालांकि यह एक सही जवाब होगा। –

+0

कूल। मैं आपके कोड को आज़माउंगा और देख सकता हूं कि यह कैसा चल रहा है। आपकी सहायता के लिए एक बार फिर से धन्यवाद। –

+3

अपडेट: श्रेणीऑफडाटा आईओएस 4 के रूप में उपलब्ध है। – steipete

1

यदि आप हिम तेंदुए का उपयोग कर रहे हैं, तो सुविधाजनक तरीका नया-श्रेणी ओफडाटा: विकल्प: सीमा: NSData में विधि जो डेटा के टुकड़े की पहली घटना की सीमा को वापस लाती है। अन्यथा, आप स्वयं की खोज करने के लिए अपने -bytes विधि का उपयोग करके स्वयं एनएसडीटा की सामग्री तक पहुंच सकते हैं।

+0

अच्छा बिंदु। मैंने यह नहीं देखा था कि -रेेंजऑफडाटा: विकल्प: रेंज: केवल 10.6 में जोड़ा गया था। –

+1

इसलिए मेरे पास यह तरीका उपलब्ध नहीं है क्योंकि मैं इसे आईफोन पर कर रहा हूं। मैं उन वर्णित पदार्थों की तुलना करने के लिए किस सी फ़ंक्शन का उपयोग करूंगा जो मैं-बाइट्स विधि से प्राप्त बफर की तलाश में हूं? कोई विचार? –

1

मुझे एक ही समस्या थी। मैंने सुझावों की तुलना में इसे दूसरे तरीके से हल किया। डेटा (मान लीजिए आपका NSData वर rawFile में संग्रहीत किया जाता है) के साथ

पहले, मैं पुन: फ़ॉर्मेट:

NSString *ascii = [[NSString alloc] initWithData:rawFile encoding:NSAsciiStringEncoding]; 

अब, आप आसानी 'एबीसीडी' या जो भी आप NSScanner वर्ग का उपयोग कर करना चाहते हैं और इस तरह स्ट्रिंग खोज कर सकते हैं स्कैनर के लिए ascii स्ट्रिंग गुजर रहा है। हो सकता है कि यह वास्तव में कुशल नहीं है, लेकिन यह तब तक काम करता है जब तक -rangeOfData विधि आईफोन के लिए भी उपलब्ध नहीं होगी।

+0

आपकी प्रतिक्रिया के लिए धन्यवाद। प्रश्न में बताए गए मेरे मानदंडों में से एक था "पूरी फाइल को स्ट्रिंग में परिवर्तित किए बिना" इसलिए यह मेरे लिए एक व्यवहार्य समाधान नहीं है। जिस समाधान के साथ आया था, उसे देखने के लिए अब मेरा मूल प्रश्न देखें। यह किसी भी डेटा की प्रतिलिपि किए बिना अच्छी तरह से काम करता है। मैं बस एनएसडीटा ऑब्जेक्ट से बाइट्स पर फिर से शुरू करता हूं जो मुझे आवश्यक चरित्र अनुक्रम की तलाश में है और फिर पहली घटना को ढूंढने के बाद सरणी में उस स्थिति में एक पॉइंटर लौटाता है। –

+0

हां मैं देखता हूं। असली बिंदु इस तरह के रूपांतरण की लागत को समझना होगा, मुझे वास्तव में इस पर कोई संकेत नहीं है। एप्पल अबू से पूछना उपयोगी हो सकता है ... उन्हें अपने मंचों में भी देखना शुरू करना है। :-) – Andy

संबंधित मुद्दे