2012-04-15 6 views
13

Cの単一リンクリストに基づくデータベースの作成に問題があります。 は、リンクリストの概念ではなく、構造体自体の文字列フィールドのためです。Cの構造体で文字列フィールドを操作するには?

これはCでの割り当てであり、私が知っている限り(私は初心者です)、Cは 'string'をデータ型として認識しません。

これは私の構造体のコードは次のようになります。

私はこのように、構造体にそれらを使用できるように、私は、文字列自身のための構造体を作ることを考えていた
typedef struct 
{ 
    int number; 
    string name; 
    string address; 
    string birthdate; 
    char gender; 
} patient; 

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

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

次に、文字列型(charの配列)の新しいデータを作成する必要がある場合は、それぞれ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には、全体的にdelcared patientがありますが、これは初期化されていません。試してみてください:

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

あなたがリードアクセスをする前に、そのメンバーも

のいずれか、それが割り当てられた境界チェック(最初'\0'に遭遇するまでコピーし、書き込みの過去を持っていないとしてstrcpy本質的に安全ですソースが長すぎる場合はメモリ)。代わりにstrncpyを使用してください。ここでは、コピーできる最大文字数を指定することができます。正しい値を渡すためにドキュメントを読んでください。オフ・バイ・ワンのエラーを作るのは簡単です。

あなただけ typedefさらに簡単に使用することができ
+0

mallocを使用している間は、型キャストしないでください(http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858)。 –

+0

「患者」はグローバルに宣言されていません。それは型定義です。しかし、グローバルであったとしても、このように初期化することはできません。 – kralyk

+0

@kralyk - 正しい、私はそれを自分で実現し、修正しました。 – Attila

0

typedef char *string; 

次に、あなたのmalloc関数は、通常のmalloc関数のようになります。文字列とメモリの割り当てに

string s = malloc(maxStringLength); 
31

Cの文字列は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; 

リンクリストの場合:

一般にリンクリストの目的は、順序付けされた要素の集合への迅速なアクセスを証明することです。 llistnumという要素(おそらく患者番号が含まれています)が含まれている場合は、実際に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のポインタとして使用したい場合はポインタに変更する必要はありません。これは本当に目が開いているありがとうございます。しかし、私はここでいくつかの質問を得ました:(a)私は新しい患者のためにレコードを挿入したいと思います、私はvoid insert()のような新しいfuctionを作らなければなりませんか?上記のtypedef構造体の構造体患者と少し混乱しているか(b)、リスト構造体に患者構造体を含む新しい(ノードを言う)を挿入する必要がありますか?リスト?これは理解できます..ありがとう。 – fleuracia

+0

リンクされたリストは、一度理解すればよく役立つ基本的な汎用データ構造の1つです。あなたがここで得られるよりも包括的な説明を見つけることは、価値ある投資となるでしょう。たくさんの良いウェブサイトや書籍があります。 –

1

をtypedefを使いたいのであれば、このインスタンスではポインタを見失って、何も得られていないので、特に良い考えではないでしょう。

これは、カウントされた文字列やその他の機能を持つものであれば違いますが、この例では、 '標準の' C文字列の実装に精通していることを本当にお勧めします。 char * '...

関連する問題