2016-10-26 7 views
0

私はファイルから読み込み、それをリンクリストに追加しようとしていて、リンクされたリストをたどってコンテンツを印刷しています。私の出力はリンクされたリスト全体を印刷するのではなく、最後の要素だけを複数回印刷するので少し問題があります。私は下にコードを掲載しており、スニペットのみを掲載しており、簡潔さのためにエラーチェックを削除しています。だから、リンクされたリストを印刷するCが機能しませんか?

typedef struct Node{ 
    char* data; 
    struct Node* next; 
} NODE; 

NODE* head = NULL; 
NODE* tail = NULL; 

int main(int argc, char* argv[]) 
{ 
    char buffer[1024]; 
    FILE* fp = fopen(argv[1], "r"); 
    while(fscanf(fp, "%1023s", buffer) == 1) 
    { 
     addNode(buffer); 
    } 
    print_linked_list(head); 
    return 0; 
} 

void print_linked_list(NODE* head) 
{ 
    NODE* ptr = head; 
    while(ptr != NULL) 
    { 
     printf("%s ", ptr -> data); 
     ptr = ptr -> next; 
    } 
} 

void addNode(char* str) 
{ 
    NODE* newNode = createNode(str); 
    if(head == tail && tail == NULL) 
    { 
     head = newNode; 
     tail = newNode; 
     head -> next = NULL; 
     tail -> next = NULL; 
    } 
    else 
    { 
     tail -> next = newNode; 
     tail = newNode; 
     tail -> next = NULL; 
    } 
} 

NODE* createNode(char* str) 
{ 
    NODE* newNode = malloc(sizeof(NODE)); 
    newNode -> data = malloc((1 + strlen(str)) * sizeof(char)); 
    newNode -> data = str; 
    newNode -> next = NULL; 
    return newNode; 
} 

ファイルは、「どのようにしている」のようないくつかのテキストが含まれている場合、私は私の出力は、「どのようにしている」が、私が得るすべては「あなたあなたあなた」であるとして印刷することを期待しています。これをどうやって解決するのですか?あなたはstrからnewNode->dataに文字列のコピー(strncpy()を)やってみたかったの

newNode -> data = malloc((1 + strlen(str)) * sizeof(char)); 
newNode -> data = str; 

答えて

2

newNode->data = str;の場合、ポインタはコピーされ、内容は(たとえば「あなたはどうですか?」)ではありません。

簡単な方法は、http://man7.org/linux/man-pages/man3/strdupa.3.html

The strdup() function returns a pointer to a new string which is a 
    duplicate of the string s. Memory for the new string is obtained 
    with malloc(3), and can be freed with free(3). 
+0

うん、それは、何らかの理由のために働くあなたは、なぜその変更の作品を説明することができる:あなたはまた、それが有効なポインタを返したことを確認するために最初のmallocの戻り値をチェックする必要がありますか? – posixKing

+1

@luforkすべてのノードのデータを同じ値に設定しています。これは 'buffer'へのポインタです。したがって、すべてのノードは同じデータを持ちます。 –

+0

ああ、ありがとう。しかし、1つの小さなクエリは、私は別のSOの質問をチェックし、誰かがstrdupは非標準であり、したがって使用すべきではないと述べた。だから、strncpyはstrdupに比べて一般的にもっと奨励されるだろうか?ありがとう – posixKing

1

newNode->data = str;から

newNode->data = strdup(str); 

かもしれない問題です。あなたはmalloc文字列のためのスペースであり、そのアドレスをnewNode->dataに割り当てて、そのアドレスにのスペースを即座に上書きします。mainbufferのアドレスであるstrのアドレスです。これによってメモリリークが発生するだけでなく、動作が説明されます。ノードを作成するたびに、bufferのアドレスにnewNode->dataを割り当てているので、最後の単語「0125」が「buffer」に格納されている場合、これはすべてのノードが印刷する文字列です。あなたが本当にやりたいことは、strの文字列を新たにmallocのスペースに入れたstrcpy(またはこれと同等のもの)です。

#include <string.h> 
.... 

if (newNode->data != NULL) 
{ 
    strcpy(newNode->data, str); 
} 
else 
{ 
    // handle error 
} 
関連する問題