2017-12-04 6 views
0
#include <stdio.h> 
#include <stdlib.h> 

#define MAXLINE 80 

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

int get_Line(FILE *fp, char s[], int lim); 
Node* addNode(Node *front, char *data); 
Node* fillList(Node *front, char *txtFile, int lim); 

int main() { 
    Node *dataFront = NULL; 
    dataFront = fillList(dataFront,"data.txt",MAXLINE); 
    printf("%s\n",dataFront->data); //prints blank line 
    return 0; 
} 

int get_Line(FILE *fp, char s[], int lim){ 
    int c, i; 
    for (i = 0; i < lim-1 && (c=getc(fp)) != EOF && c != '\n'; ++i) 
     s[i] = c; 
    if (c == '\n'){ 
     s[i] = c; 
     ++i; 
    } 
    s[i] = '\0'; 
    return i; 
} 

Node* addNode(Node *front, char *data){ 
    Node *newNode = (Node*)malloc(sizeof(Node)); 
    newNode->data = data; 
    newNode->next = NULL; 
    if(front!= NULL) 
     newNode->next = front; 
    front = newNode; 
    return front; 
} 

Node* fillList(Node *front, char *txtFile, int lim){ 
    FILE *fp = fopen(txtFile,"r"); 
    char data[lim]; 
    while(get_Line(fp,data,lim) > 0){ 
     front = addNode(front, data); 
     printf("%s\n",front->data); //prints the string member of Node 
            //front just fine 
    } 
    printf("%s\n",front->data); //prints blank line 
    fclose(fp); 
    return front; 
} 

텍스트 파일에서 줄을 읽음으로써 문자열을 포함하는 노드 목록을 만듭니다. 텍스트 파일은 무엇이든 될 수 있습니다.내 노드의 String 멤버가 생성 된 후 빈 줄을 인쇄하는 이유는 무엇입니까?

print 문을 디버깅하는 데 fillList 함수에 넣습니다. 함수에서 fillList 인쇄 front-> while 루프 내의 데이터는 작동하지만 while 루프 외부에서는 빈 줄이 인쇄됩니다. 주 인쇄에서 문자열 멤버는 빈 줄을 제공합니다. 이 문제를 해결하는 데 도움이 필요해. 떨어져 내 디버깅 get_Line 및 addNode 잘 작동합니다.

편집 1 : 내 텍스트 파일 - data.txt로이 - 다음과 같은 텍스트가 포함 - txt file screenshot - 내 출력은 JPEG에서 볼 수있다 : output screenshot

+0

프로그램의 출력은 무엇입니까? 빈 줄이 무엇을 의미하는지 정확히 알지 못합니다. 데이터 가운데, 이전, 이후에 오는 것입니까? 아니면 유일한 것이 인쇄 되었습니까? 프로그램의 결과를 포함하도록 질문을 업데이트해야합니다. –

+0

파일의 마지막에 두 개의'\ n'을 포함하고 있지 않습니까? 또한 코드에 ** 큰 ** 문제가 있습니다. – coderredoc

+1

'newNode-> data = strdup (data)'는 일부 UB를 수정합니다 – pm100

답변

2

문제는 당신 addNode 기능입니다 : 여기

newNode->data = data; 

data 파라미터에 정의 data 배열에 대응 fillList. 따라서 각 목록 요소의 data 구성원은 배열을 다시 가리키고 fillList입니다. 즉, 모든 목록 요소에는 동일한 데이터가 포함됩니다. 그런 다음 while 루프를 그대로두면 data에 빈 문자열이 포함됩니다. 모든 노드 data은 로컬 data 배열을 가리키고 있으므로 front-data을 인쇄하면 빈 문자열이 나타납니다.

fillList에서 돌아 오면 목록 요소가 이제 범위를 벗어난 지역 변수를 가리 킵니다. 그런 다음 printfmain에서 호출 할 때 잘못된 포인터를 역 참조하여 undefined behavior을 호출합니다. main에서 인쇄 할 때 표시되는 빈 줄은 잘못된 메모리 위치에있는 것입니다. 일관성을 위해 그 beahvior에 의존 할 수 없습니다.

각 목록 요소에 대해 새 버퍼를 할당하고 해당 버퍼에 문자열을 복사하여이 문제를 해결할 수 있습니다. 한 번 strdup를 사용하여 양쪽을 수행 할 수 있습니다

newNode->data = strdup(data); 

은 또한 당신은 목록에서 노드와 그들이 그렇게 포함 된 문자열을 메모리 누수가없는 프로그램이 모두 할당을 취소 종료 할 때 코드를 추가 할 수 있습니다 .

+0

감사! 방금 문제를 해결하려고했는데 제대로 작동했습니다. –

+0

나는 무슨 일이 일어나고 있는지 모르겠다. 정말로.이것은 OP에서 이런 종류의 행동을하는 것은 매우 이상합니다. OP 스위치를 한 번 더 내 대답을 삭제합니다. – coderredoc

+0

이 OP 동작은 정말 이상합니다. OP 선택을 취소하면 답변을 삭제합니다. 좋은 대답은 +1. – coderredoc