2012-04-15 18 views
13

मुझे सी, में एक सिंगल-लिंक्ड सूची के आधार पर डेटाबेस बनाने में परेशानी हो रही है, लिंक्ड सूची अवधारणा के बजाय नहीं, बल्कि संरचना में स्ट्रिंग फ़ील्ड।सी संरचना में स्ट्रिंग फ़ील्ड के साथ कैसे काम करें?

यह सी में एक असाइनमेंट है और जहां तक ​​मुझे पता है (मैं एक नौसिखिया हूं), सी डेटा प्रकार के रूप में 'स्ट्रिंग' को पहचान नहीं पाता है।

typedef struct 
{ 
    int number; 
    string name; 
    string address; 
    string birthdate; 
    char gender; 
} patient; 

typedef struct llist 
{ 
    patient num; 
    struct llist *next; 
} list; 

मैं तार के लिए एक struct बनाने की सोच रहा था खुद को इतना है कि मैं struct में उन्हें इस्तेमाल कर सकते हैं, इस तरह::

यह वही मेरी struct कोड लगता है कि है

typedef struct string 
{ 
    char *text; 
} *string; 

तब मैं malloc() उनमें से प्रत्येक को स्ट्रिंग प्रकार (चार की सरणी) के नए डेटा को बनाने की आवश्यकता होने पर होगा।

typedef struct string 
{ 
    char *text; 
} *string; 

int main() 
{ 
    int length = 50; 
    string s = (string) malloc(sizeof string); 
    s->text = (char *) malloc(len * sizeof char); 
    strcpy(s->text, patient.name->text); 
} 

क्या कोई इसे समझने में मेरी सहायता कर सकता है?
धन्यवाद।

उत्तर

0

यह काम नहीं करता:

string s = (string)malloc(sizeof string); 

string एक सूचक को संदर्भित करता है, आप संरचना के ही आकार की जरूरत है:

string s = malloc(sizeof (*string)); 

नोट कलाकारों की कमी के रूप में अच्छी तरह से (void* से रूपांतरण (malloc का रिटर्न प्रकार) पूरी तरह से किया जाता है)।

इसके अलावा, आपके main में, आपके पास वैश्विक स्तर पर patient है, लेकिन यह अनियमित है। प्रयास करें:

patient.number = 3;  
patient.name = "John";  
patient.address = "Baker street";  
patient.birthdate = "4/15/2012";  
patient.gender = 'M';  

इससे पहले कि आप पढ़ने के लिए पहुँच अपने सदस्यों

इसके अलावा, strcpy के किसी भी स्वाभाविक असुरक्षित के रूप में यह सीमा जाँच (प्रथम '\0' तक की प्रतिलिपि बनाएगा का सामना करना पड़ा है नहीं है, लेखन अतीत आवंटित स्मृति अगर स्रोत बहुत लंबा है)। इसके बजाय strncpy का उपयोग करें, जहां आप कम से कम वर्णित वर्णों की अधिकतम संख्या निर्दिष्ट कर सकते हैं - यह सुनिश्चित करने के लिए कि आप सही मान पास करते हैं, दस्तावेज़ को पढ़ें, एक-एक-एक त्रुटि बनाना आसान है।

+0

मॉलोक का उपयोग करते समय आपको [टाइपस्टकास्ट नहीं होना चाहिए] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858)। –

+0

नहीं 'रोगी' वैश्विक स्तर पर घोषित नहीं किया गया है, यह एक टाइपडीएफ है। लेकिन अगर यह वैश्विक था, तो भी आप इसे इस तरह शुरू नहीं करेंगे। – kralyk

+0

@kralyk - सही, मैंने इसे स्वयं महसूस किया और सही किया। – Attila

0

तुम सिर्फ इस्तेमाल कर सकते हैं एक और भी आसान typedef:

typedef char *string; 

फिर, अपने malloc एक सामान्य malloc दिखाई देगा:

string s = malloc(maxStringLength); 
31

तार और स्मृति आवंटन पर:

सी में एक स्ट्रिंग सिर्फ char एस का अनुक्रम है, इसलिए आप char * का उपयोग कर सकते हैं या एक char सरणी भी आप एक स्ट्रिंग डेटा प्रकार का उपयोग करना चाहते: फिर

typedef struct  { 
    int number; 
    char *name; 
    char *address; 
    char *birthdate; 
    char gender; 
} patient; 

आप संरचना खुद के लिए स्मृति को आबंटित करने की जरूरत है, और तार से प्रत्येक के लिए:

patient *createPatient(int number, char *name, 
    char *addr, char *bd, char sex) { 

    // Allocate memory for the pointers themselves and other elements 
    // in the struct. 
    patient *p = malloc(sizeof(struct patient)); 

    p->number = number; // Scalars (int, char, etc) can simply be copied 

    // Must allocate memory for contents of pointers. Here, strdup() 
    // creates a new copy of name. Another option: 
    // p->name = malloc(strlen(name)+1); 
    // strcpy(p->name, name); 
    p->name = strdup(name); 
    p->address = strdup(addr); 
    p->birthdate = strdup(bd); 
    p->gender = sex; 
    return p; 
} 

यदि आप केवल हूँ जरूरत है कुछ patient रों, आप और अधिक स्मृति आवंटन की कीमत पर स्मृति प्रबंधन से बच सकते हैं की तुलना में आप वास्तव में जरूरत है:

typedef struct  { 
    int number; 
    char name[50];  // Declaring an array will allocate the specified 
    char address[200]; // amount of memory when the struct is created, 
    char birthdate[50]; // but pre-determines the max length and may 
    char gender;   // allocate more than you need. 
} patient; 

लिंक्ड सूचियों पर:

सामान्य रूप से, एक लिंक्ड सूची का उद्देश्य तत्वों के आदेशित संग्रह तक त्वरित पहुंच साबित करना है। यदि आपके llist में num (जो संभावित रूप से रोगी संख्या शामिल है) नामक एक तत्व होता है, तो आपको वास्तविक patient स्वयं को रखने के लिए अतिरिक्त डेटा संरचना की आवश्यकता होती है, और आपको हर बार रोगी संख्या को देखना होगा।

इसके बजाय, अगर आप

typedef struct llist 
{ 
    patient *p; 
    struct llist *next; 
} list; 

घोषित तो प्रत्येक तत्व एक patient संरचना के लिए एक सीधा सूचक है, और आप इस तरह डेटा का उपयोग कर सकते हैं: एक ओर जहां रिचर्ड तुम क्या चाहते है

patient *getPatient(list *patients, int num) { 
    list *l = patients; 
    while (l != NULL) { 
    if (l->p->num == num) { 
     return l->p; 
    } 
    l = l->next; 
    } 
    return NULL; 
} 
+0

आह इसलिए मूल रूप से मुझे शाब्दिक रूप से स्टिंग प्रकार का उपयोग करने की आवश्यकता नहीं है और इसे पॉइंटर में संशोधित करने की आवश्यकता नहीं है यदि मैं इसे char के सूचक के रूप में उपयोग करना चाहता हूं। धन्यवाद, यह वास्तव में आकर्षक है। लेकिन मुझे यहां कुछ प्रश्न मिल गए हैं: (ए) कहें कि मैं एक नए रोगी के लिए एक रिकॉर्ड डालना चाहता हूं, क्या मुझे शून्य डालने() की तरह एक नई नीलामी करना है? उपरोक्त टाइपपीफ स्ट्रक्चर (बी) के लिए स्ट्रक्चर मरीज के साथ थोड़ा उलझन में आया है या क्या मुझे एक नया डालना है (एक नोड कहें) जिसमें सूची संरचना में रोगी संरचना होगी, कहें, एक नया नोड सूची? क्या यह समझ में आता है .. बहुत बहुत धन्यवाद। – fleuracia

+0

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

1

यदि आप टाइपिफ़ के साथ जाना चाहते हैं, तो मैं सुझाव दूंगा कि शायद इस उदाहरण में यह विशेष रूप से अच्छा विचार नहीं है, क्योंकि आप इसे पॉइंटर होने की दृष्टि से खो देते हैं, जबकि कुछ हासिल नहीं करते हैं।

यदि आप इसे एए गिनती स्ट्रिंग या अतिरिक्त कार्यक्षमता वाले कुछ का इलाज कर रहे थे, तो यह अलग हो सकता है, लेकिन मैं वास्तव में अनुशंसा करता हूं कि इस उदाहरण में, आप केवल 'मानक' सी स्ट्रिंग कार्यान्वयन से परिचित हो जाएं ' char * '...

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