सी

2010-04-10 3 views
6

में डबल विभाजन। उदाहरण के लिए मैं अपने txt फ़ाइल में इस लाइन है:सी

1|1,12;7,19;6,4;8,19;2,2
आप देख सकते हैं, यह 2 भागों, | द्वारा अलग है। मुझे ; विभाजक का उपयोग करके दोनों भागों को प्राप्त करने में कोई समस्या नहीं है, और दूसरे भाग 1,12;7,19;6,4;8,19;2,2 को अलग करना है। लेकिन मुझे प्रत्येक सेट की पहली और दूसरी संख्या प्राप्त करने के लिए , द्वारा आगे अलग करने में समस्याएं हैं।

यह मेरे वर्तमान कोड है:

result = strtok(result, ";"); 

    while(result != NULL) { 
     printf("%s\n", result); 
     result = strtok(NULL, ";"); 
    } 

यह मेरे आउटपुट:

1,12
7,19
6,4
8,19
2,2

ठीक है, बढ़िया। लेकिन जब मैं 'strtok' (मैं बंटवारे के लिए इस पद्धति का उपयोग कर रहा हूँ) इस तरह का प्रयास करें:

result = strtok(result, ";"); 

while(result != NULL) { 
    //printf("%s\n", result); 
    help = strtok(result, ",");  
    while(help != NULL) { 
     printf("<%s>", help); 
     help = strtok(NULL, ","); 
    } 

    result = strtok(NULL, ";"); 
} 

मैं केवल मिल "< 1>, < 12>" इस सेट में केवल एक सेट मौजूद है संख्याओं का मैं समझ नहीं पा रहा हूं कि बाकी संख्याएं कहां हैं। इसके बजाय, उत्पादन किया जाना चाहिए: < 1>, < 12>, < 7>, < 19>, < 6>, < 4>, < 8>, < 19>, < 2>, < 2>। क्या कोई समाधान दे सकता है, इस सेट के प्रत्येक सेट की प्रत्येक सेट को कैसे प्राप्त करें। शायद अन्य विधियां हैं या मैं कुछ गलत कर रहा हूं :)

धन्यवाद!

उत्तर

2

char * strtok (char * str, const char * delim); (मैन पेजों से)
delim तर्क वर्णों के एक सेट को निर्दिष्ट करता है जो पार्सड स्ट्रिंग में टोकन को सीमित करता है। कॉलर एक ही स्ट्रिंग को पार्स करने वाली लगातार कॉल में delim में अलग-अलग तार निर्दिष्ट कर सकता है।

तो, सभी नंबरों को पाने के लिए परिसीमक के रूप में ; और , दोनों का उपयोग करें।

//this will delimit result whenever ";" or "," is found 
result = strtok(result, ";,"); 

while(result != NULL) { 
    printf("%s\n", result); 
    result = strtok(NULL, ";,"); 
} 
1

पहले strtok विभाजन कई अशक्त में मूल रूप से समाप्त तार। दूसरा स्ट्रोक केवल इन स्ट्रिंग्स के पहले पर लागू होता है - यह पहले स्ट्रोक कॉल द्वारा बनाए गए पहले नल-टर्मिनेटर पर रुक जाता है। आपको पहले बनाए गए तारों के प्रत्येक के लिए दूसरा स्ट्रोक कोड कॉल करने की आवश्यकता है।

5

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

+0

+1,:

आप रैत्रांत संस्करण strtok_r() उपलब्ध है, तो आप अपने कोड तो जैसे कि यह उपयोग करने के लिए बदल सकते हैं। – codaddict

0

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

या, यदि आप नेस्टेड लूप, see here का उपयोग करना चाहते हैं।

+0

वाह। धन्यवाद दोस्तों! बहुत अच्छा काम करता है! कभी नहीं सोचा था कि यह इतना आसान था। – Dmitri

0

के रूप में अन्य लोगों ने बताया है, strtok() रैत्रांत नहीं है - यह स्ट्रिंग यह पार्स करने के बारे में आंतरिक स्थिति को बनाए रखता है, तो यह एक साथ दो अलग तार पार्स करने के लिए (जिसके लिए दो अलग-अलग गैर शून्य मान का मतलब है नहीं किया जा सकता है अपने पहला तर्क, इसलिए आपकी स्थिति गिना जाता है)। नेस्टेड सीमा की ओर इशारा करते के लिए

char *st_result, *st_help; 
result = strtok_r(result, ";", &st_result); 

while (result) { 
    printf("[%s]", result); 
    help = strtok_r(result, ",", &st_help);  
    while (help) { 
     printf("<%s>", help); 
     help = strtok_r(NULL, ",", &st_help); 
    } 

    result = strtok_r(NULL, ";", &st_result); 
}