2010-12-28 18 views
7

के साथ सी में दो बार स्ट्रिंग को टोकन करना I csv स्ट्रिंग को पार्स करने के लिए c में strtok() का उपयोग कर रहा हूं। सबसे पहले मैं यह जानने के लिए टोकननाइज़ करता हूं कि कितने टोकन हैं इसलिए मैं सही आकार की एक स्ट्रिंग आवंटित कर सकता हूं। फिर मैं उसी वैरिएबल का उपयोग करके जाता हूं जिसे मैंने आखिरी बार टोकननाइजेशन के लिए इस्तेमाल किया था। हर बार जब मैं इसे दूसरी बार करता हूं हालांकि strtok(NULL, ",")NULL देता है भले ही अभी भी अधिक टोकन पार्स हैं। क्या कोई मुझे बता सकता है कि मैं क्या गलत कर रहा हूं?strtok()

char* tok; 
int count = 0; 
tok = strtok(buffer, ","); 
while(tok != NULL) { 
    count++; 
    tok = strtok(NULL, ","); 
} 

//allocate array 

tok = strtok(buffer, ","); 
while(tok != NULL) { 
    //do other stuff 
    tok = strtok(NULL, ","); 
} 

तो उस दूसरी तरफ लूप यह हमेशा टोकन के बाद समाप्त होता है, भले ही अधिक टोकन हों। क्या कोई जानता है कि मैं क्या गलत कर रहा हूं?

+2

यह स्पष्ट रूप से हर कोई जानता है कि इन दिनों 'strtok() 'क्या है, लेकिन किसी ने दस्तावेज़ को पढ़ा नहीं है? जब मैं सी सीख रहा था तब किसी ने मुझे इसके बारे में नहीं बताया, लेकिन जैसे ही मुझे इसके बारे में पता था, मैंने इसे पढ़ा। –

उत्तर

16

strtok() उस स्ट्रिंग को संशोधित करता है जो इसे संचालित करता है, जिसमें डिलीमीटर वर्णों को नल के साथ बदल दिया जाता है। तो यदि आप इसे एक से अधिक बार उपयोग करना चाहते हैं, तो आपको एक प्रतिलिपि बनाना होगा।

+4

+1: और यही कारण है कि 'strtok() 'का उपयोग अक्सर इस तरह का अच्छा विचार नहीं है ... –

+0

आप जीतते हैं। तेज़ उत्तर के लिए +1। – Septagram

2

एक प्रतिलिपि बनाने की आवश्यकता नहीं है - strtok() उस टोकनिंग को स्ट्रिंग को संशोधित करता है, लेकिन ज्यादातर मामलों में इसका मतलब यह है कि स्ट्रिंग पहले से ही टोकननाइज्ड है यदि आप टोकन से फिर से निपटना चाहते हैं।

यहाँ अपने कार्यक्रम अपने पहले पास के बाद टोकन कार्रवाई करने के लिए एक सा संशोधित है:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    int i; 
    char buffer[] = "some, string with , tokens"; 

    char* tok; 
    int count = 0; 
    tok = strtok(buffer, ","); 
    while(tok != NULL) { 
     count++; 
     tok = strtok(NULL, ","); 
    } 


    // walk through the tokenized buffer again 
    tok = buffer; 

    for (i = 0; i < count; ++i) { 
     printf("token %d: \"%s\"\n", i+1, tok); 
     tok += strlen(tok) + 1; // get the next token by skipping past the '\0' 
     tok += strspn(tok, ","); // then skipping any starting delimiters 
    } 

    return 0; 
    } 

ध्यान दें कि यह दुर्भाग्य से जटिल काम की तुलना में मैं पहले तैनात है - strspn() करने के लिए कॉल लंघन के बाद प्रदर्शन किया जा करने की जरूरत है '\ strtok()strtok() के बाद 01210 द्वारा रखे गए टोकन के लिए किसी भी प्रमुख डेलीमीटर अक्षर को छोड़ देगा (स्रोत में डेलीमीटर चरित्र को प्रतिस्थापित किए बिना)।

+0

एक और तरीका एक सरणी में पहले पास से टोकन पॉइंटर्स को स्टोर करना होगा। बेशक, इसका मतलब टोकन या गतिशील सरणी की अधिकतम संख्या होगी। लेकिन वह भी काम कर सकता है। –

1

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

char * strsep (char ** string, char * delim);

char * string; चार * टोकन; टोकन = स्ट्रसेप (& स्ट्रिंग, ",");

स्ट्रोक का सामान्य पाठ्यक्रम में सी कोर्स का उपयोग किया जाता है - स्ट्रसेप का उपयोग करें, यह बहुत बेहतर है। :-) "ओह बकवास पर भ्रमित नहीं हो रहा है - मुझे अभी भी नल में गुजरना है cuz strtok मेरी स्थिति खराब कर दिया।"

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