2012-11-21 5 views
0

구조체 anangramInfo의 포인터를 전달하는 함수 호출 userInteractive (* anangramInfo)가 있으며이 구조체에는 실제 anagrams에 대한 포인터 "anagramPointer"가 들어 있습니다. 그래서, 나는 사용자로부터 표준을 얻는다. 포인터를 찾으려면 bsearch의 키로 사용하십시오. anagram은 동일한 anangram.sorted를가집니다. 키가 anagram.sorted와 일치하지 않을 때까지 포인터를 왼쪽으로 이동 한 다음 anagram.sorted가 일치하지 않을 때까지 anagram.word를 오른쪽으로 다시 이동하십시오. 그러나 그것은 나에게 분할 문제Csearch 세그먼트 화 오류가 발생했습니다

의 원인
#include <string.h> 
#include <errno.h> 
#include <ctype.h> 
#include "anagrams.h" 
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/types.h> 

#define SIZE 80 

//struct 
struct anagram { 
    char word[SIZE]; 
    char sorted[SIZE]; 
}; 

struct anagramInfo { 
    struct anagram *anagramPtr; 
    int    numOfAnagrams; 
}; 



/* qsort struct comparision function (product C-string field) */ 
int sortedMemberCompare(const void *ptr1, const void *ptr2) 
{ 
    struct anagram *ia = (struct anagram *)ptr1; 
    struct anagram *ib = (struct anagram *)ptr2; 

    return strcmp(ia->sorted, ib->sorted); 
    /* strcmp functions works exactly as expected from 
    comparison function */ 
} 

void userInteractive(struct anagramInfo *anagramInfoPtr){ 

    struct anagram a; 
    char data[SIZE]; 
    char *pos; 

    printf("Enter a word to search for anagrams [^D to exit]:\n"); 
    fgets(data, SIZE, stdin); 

    //get ripe of the '\n' 
    pos=strchr(data, '\n'); 
    *pos = '\0'; 

    strncpy(a.word,data,sizeof(data)); 

    //lowercase word 
    int i; 
    for(i=0;data[i] != '\0';i++) 
     { 
     data[i]=(char)tolower(data[i]); 
     } 

    /* sort array using qsort functions */ 
    qsort(data,strlen(data), 1, charCompare); 

    strncpy(a.sorted,data,sizeof(data)); 

    //struct pointer to the elements 
    struct anagram *ptr= (struct anagram *)bsearch(a.sorted,anagramInfoPtr-> anagramPtr ->sorted,anagramInfoPtr-> numOfAnagrams,sizeof(struct anagram),sortedMemberCompare); 

    printf(ptr->word); 

    while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) { 
     ptr--; 
    } 

    while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) { 
     printf(ptr ->word); 
     printf(" "); 
     ptr++; 
    } 

} 
+0

아마 문자열의 일부는 80 개 문자 길이 될 일이? - >> strncpy()의 매뉴얼 페이지를 읽어보십시오 – wildplasser

+0

anagramInfo 구조체는 어떻게 초기화합니까? –

+0

주 코드에서 초기화합니다. – keivn

답변

2

귀하의 감독이 bsearch가 연속 배열에서 검색되지 않는 것입니다; 당신이 분류 문자열를 검색하기 때문에 그것도, 바로 이곳에서 검색되지 않지만이 아나그램의 정렬 된 회원을 검색한다고 : bsearch가 실패하고 NULL을 반환 할 때 다음

struct anagram *ptr = (struct anagram *)bsearch(&a, 
      anagramInfoPtr-> anagramPtr, 
      anagramInfoPtr-> numOfAnagrams, 
      sizeof(struct anagram), 
      sortedMemberCompare); 

, 당신 ptrNULL인지 확인하고 사용하십시오. 그러므로 segfault. Ctrl-D에서 NULL도 확인하지 마십시오.

테스트

이 수정 된 버전입니다 - 나는 charCompare 기능을 다시 추가하고 패션 후, 작동하게하기 위해 다섯 가지 고정 된 문자열과 main()을 채찍질.

#include <string.h> 
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <sys/types.h> 

#define SIZE 80 

//struct 
struct anagram { 
    char word[SIZE]; 
    char sorted[SIZE]; 
}; 

struct anagramInfo { 
    struct anagram *anagramPtr; 
    int    numOfAnagrams; 
}; 

/* qsort struct comparision function (product C-string field) */ 
int sortedMemberCompare(const void *ptr1, const void *ptr2) 
{ 
    struct anagram *ia = (struct anagram *)ptr1; 
    struct anagram *ib = (struct anagram *)ptr2; 

    return strcmp(ia->sorted, ib->sorted); 
    /* strcmp functions works exactly as expected from 
    comparison function */ 
} 

int charCompare(const void *a, const void *b) 
{ 
     const char *aa = a, *bb = b; 
     if (*aa < *bb) 
       return -1; 
     if (*aa == *bb) 
       return 0; 
     return 1; 
} 

void userInteractive(struct anagramInfo *anagramInfoPtr){ 

    struct anagram a; 
    char data[SIZE]; 
    char *pos; 

    printf("Enter a word to search for anagrams [^D to exit]:\n"); 
    fgets(data, SIZE, stdin); 

    //get ripe of the '\n' 
    pos=strchr(data, '\n'); // In Windows this might be a "\r" maybe? 
    if (NULL == pos) 
     exit(0); 

    *pos = '\0'; 

    strncpy(a.word,data,sizeof(data)); 

    //lowercase word 
    int i; 
    for(i=0;data[i] != '\0';i++) 
    { 
     data[i]=(char)tolower(data[i]); 
    } 

    /* sort array using qsort functions */ 
    qsort(data, strlen(data), 1, charCompare); 
    strncpy(a.sorted,data,sizeof(data)); 

    //struct pointer to the elements 
    struct anagram *ptr = (struct anagram *)bsearch(&a, 
       anagramInfoPtr-> anagramPtr, 
       anagramInfoPtr-> numOfAnagrams, 
       sizeof(struct anagram), 
       sortedMemberCompare); 

    // You must check that ptr is not NULL. 
    if (NULL == ptr) 
    { 
     printf("Not found\n"); 
     return; 
    } 

    printf("Found: %s\n", ptr->word); 

    /* Here there is a subtle error. If you find the FIRST item of the list, 
     this code will position itself BEFORE THE BEGINNING of the list, and 
     run a strncmp() against who knows what. Other segfault lurking! */ 

    while(ptr > anagramInfoPtr -> anagramPtr && strncmp(ptr ->sorted,a.sorted,strlen(a.sorted))==0) { 
     ptr--; 
    } 

    // while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) { 
    // ptr--; 
    //} 

    // Here too you should check you do not pass max number of anagrams, 
    // if you hit the last item of the lot. 
    while(strncmp(ptr ->sorted,a.sorted,sizeof(a.sorted))==0) { 
     printf(ptr ->word); 
     printf(" "); 
     ptr++; 
    } 

} 

int main() 
{ 
     int i; 
     struct anagramInfo *root; 

     root = malloc(sizeof(struct anagramInfo)); 

     root->numOfAnagrams  = 5; 
     root->anagramPtr  = malloc(root->numOfAnagrams * sizeof(struct anagram)); 

     strcpy(root->anagramPtr[0].word, "oriental"); 
     strcpy(root->anagramPtr[1].word, "teaching"); 
     strcpy(root->anagramPtr[2].word, "senator"); 
     strcpy(root->anagramPtr[3].word, "admirer"); 
     strcpy(root->anagramPtr[4].word, "rescued"); 

     for (i = 0; i < root->numOfAnagrams; i++) 
     { 
      int j; 
      for (j = 0; root->anagramPtr[i].word[j]; j++) 
       root->anagramPtr[i].word[j] = tolower(root->anagramPtr[i].word[j]); 
      strcpy(root->anagramPtr[i].sorted, root->anagramPtr[i].word); 
      qsort(root->anagramPtr[i].sorted, strlen(root->anagramPtr[i].sorted), 1, charCompare); 
     } 
     qsort(root-> anagramPtr, root-> numOfAnagrams, sizeof(struct anagram), sortedMemberCompare); 
     for (;;) 
      userInteractive(root); 
    } 

실행

$ gcc -W -Wall -o anagram anagram.c 
$ ./anagram 
Enter a word to search for anagrams [^D to exit]: 
treason 
Found: senator 

Enter a word to search for anagrams [^D to exit]: 
cheating 
Found: teaching 

Enter a word to search for anagrams [^D to exit]: 
relation 
Found: oriental 

Enter a word to search for anagrams [^D to exit]: 

$