2016-09-07 3 views
1

파일의 단어를 이진 트리에 삽입하려고합니다. 삽입 기능은 fscanf 이후에 모든 읽기 문자열을 인쇄하려고 할 때 파일을 읽지 않을 때 작동합니다 그것도 작동하지만 트리에 삽입하려고하면 파일의 마지막 문자열 만 읽습니다. 왜 이런 일이 발생합니까?파일에서 마지막 단어 만 읽는 Fscanf

while(1){ 

    if(fscanf(f,"%s %d",string,&x)==EOF) 
      break; 

     tree=insert(tree,string,x); 
    } 
+1

삽입하기 전에'string'의 사본을 만들지 않습니다. 'insert' 함수는 단지 포인터를 저장하는 것이고, 모든 트리 엔트리는 같은 문자열을 가리 킵니다. – Barmar

+0

코드의 나머지 부분을 추측하지 못하도록 버그를 보여주는 완벽한 예제 프로그램을 제공하십시오. –

답변

1

문자열의 복사본을 만들지 않고 트리에 지정한 포인터 만 저장합니다. 모든 트리 항목에는 동일한 문자열에 대한 포인터가 포함되어 있으므로 fscanf에 전화 할 때마다 덮어 쓰게됩니다.

동일한 문제가 x 인수에서 발생하며 매번 동일한 포인터를 전달합니다. 각 값에 대해 새로 int을 할당해야합니다.

while (1) { 
    if (fscanf(f, "%s %d", string, x) == EOF) { 
     break; 
    } 
    char *new_str = malloc(strlen(string)+1); 
    strcpy(new_str, string); 
    int *new_int = malloc(sizeof(*x)); 
    *new_int = *x; 
    tree = insert(tree, new_str, new_int); 
} 
+0

이것은 항상 같은 int *를 삽입합니다. –

+0

@RolandIllig 아니요. 정수는 값으로 함수에 전달됩니다. – Barmar

+0

하지만'x'는'int'가 아니며'int *'입니다. 그렇지 않으면'fscanf'를 호출하면 정의되지 않은 동작이 호출됩니다. –

0

코드는 다음과 같아야합니다

while (fscanf(f, "%s %d", string, &val) == 2) { 
    char *copy = malloc(strlen(string) + 1); 
    if (copy == NULL) 
     break; 
    strcpy(copy, string); 
    insert(copy, val); 
} 

주 두 필드를 읽을 수 있다면 확인 fscanf에 대한 오류 처리. 또한 val 앞에 &이 있으므로 컴파일러 경고가 표시되지 않습니다. 그런데 사용 가능한 모든 컴파일러 경고를 활성화해야하므로 직접 버그를 검색 할 필요가 없습니다.

+0

'insert()'의 두 번째 인수는'int *'이어야하며'int'를 전달합니다. – Barmar

+0

'int '를 삽입하는 것이이 경우에는 더 합리적이라고 생각합니다. 그러나 이것은 질문에서 분명하지 않습니다. –

+0

트리는 모든 유형의 데이터를 저장할 수 있도록 설계 될 수 있으므로 값은'void *'가됩니다. – Barmar

관련 문제