2010-07-29 6 views
0

J'implémente un arbre de connaissances en c qui peut lire à partir d'un fichier. Je reçois une erreur de segmentation dans ma nouvelle fonction Je ne suis pas en mesure de tester le reste de mon code avec ce problème. Je n'ai pas beaucoup d'expérience avec c. Toute aide serait grandement appréciée.Seg Faute dans l'arbre des connaissances

mon fichier .c #include #include #include "animal.h" #include #include

/*returns a new node for the given value*/ 
struct Node * newNode (char *newValue) 
{ 
struct Node * tree; 
tree = (struct Node*)malloc(sizeof(struct Node)); 
tree -> value = newStr(newValue); 
return tree; 
} 


/* returns a new string with value passed as an argument*/ 
char * newStr (char * charBuffer) 
{ 
int i; 
int length = strlen(charBuffer); 
char newStr; 
if(charBuffer[0] == 'A' || charBuffer[0] == 'Q'){ 
    for(i=1; i<length; i++) 
     newStr += charBuffer[i]; 
} 
return (newStr + "\0"); 
} 

/*Read from a File and create a tree*/ 
struct Node * readATree(FILE * f) 
{ 
    char c; 
    char buffer[100]; 
    struct Node * newTree; 
    c = fgetc(f); 
    if (c == 'A'){ 
    fgets(buffer, 100, f); 
    newTree = newNode(buffer); 
    newTree -> left = NULL; 
    newTree -> right = NULL; 
    } 
    else{ 
    fgets(buffer, 100, f); 
    newTree = newNode(newStr(buffer)); 
    newTree->left = readATree(f); 
    newTree->right = (struct Node *) readAtree(f); 
    } 
    return newTree; 

} 

/*Write Tree to a File*/ 
void writeAFile(struct Node* tree, FILE * f) 
{ 
    char buffer[100]; 
    strcpy(buffer, tree->value); 
    if(tree != 0){ 
     if(tree->left == NULL && tree->right == NULL){ 
      fputc((char)"A", f); 
      fputs(buffer,f); 
     } else{ 
      fputc((char)"Q",f); 
      fputs(buffer,f); 
      writeAFile(tree->left, f); 
      writeAFile(tree->right,f); 
     } 
    } 
} 

/*The play should start from here*/ 
int main(){ 
    struct Node* node; 
    struct Node* root; 
    char ans[100]; 
    char q[100]; 
    FILE * f; 
    f = fopen("animal.txt", "r+"); 
    if(f != NULL) 
     readATree(f); 
    else{ 
     node = newNode("Does it meow?"); 
    node->right = NULL; 
    node->right->right=NULL; 
    node->left->left=NULL; 
    node->left=newNode("Cat"); 
    root = node; 
} 
while(node->left != NULL && node->right != NULL){ 
    printf(node->value); 
    scanf(ans); 
    if(ans[0] == (char)"Y" || ans[0] == (char)"y") 
     node = node->left; 
    else if(ans[0] == (char)"N" || ans[0] == (char)"n") 
     node = node->right; 
    else 
     printf("That is not a valid input.\n"); 
} 
if(ans[0] == (char)"Y" || ans[0] == (char)"y") 
    printf("I win!"); 
else if(ans[0] == (char)"N" || ans[0] == (char)"n"){ 
    printf("What is your animal"); 
    scanf(ans); 
    printf("Please enter a yes or no question that is true about %s?\n", ans); 
    scanf(q); 
    node->right = newNode(q); 
    node->right->left = newNode(ans); 
    node->right->right = NULL; 
} 
writeAFile(root,f); 
fclose(f); 
return 0; 
} 

fichier .h #include

struct Node { 
char *value; 
struct Node * left; 
struct Node * right; 
}; 

struct Node * newNode (char *newValue) ; 
char * newStr (char * charBuffer); 
struct Node * readATree(FILE * f); 
void writeAFile(struct Node* tree, FILE * f); 
+3

Un commentaire général: Depuis presque toutes vos fonctions ont * quelque chose * mal avec eux, il est surprenant de constater que vous avez à cette quantité de code avant de remarquer que quelque chose est mal et essayant de le réparer. Je suggère de compiler, de tester et de déboguer votre code plus fréquemment au fur et à mesure que vous l'écrivez, afin que le processus soit plus gérable. –

+0

Je pense que la partie du début de votre fichier .c n'est pas formatée en 'code' – nategoose

Répondre

0

« + "opérateur comme concaténation de chaîne ne fonctionne pas dans c. Si vous souhaitez réellement copier la chaîne, utilisez strdup(). Cette fonction alloue de la mémoire et y copie la chaîne. N'oubliez pas de libérer la mémoire allouée lorsque vous avez fini de l'utiliser.

1
char * newStr (char * charBuffer) 
{ 
    int i; 
    int length = strlen(charBuffer); 
    char newStr; 
    if(charBuffer[0] == 'A' || charBuffer[0] == 'Q'){ 
    for(i=1; i<length; i++) 
     newStr += charBuffer[i]; 
    } 
    return (newStr + "\0"); 
} 

Eh bien, il y a quelques petites choses intéressantes ici ... Pour descendre à pointes en laiton, vous essayez de copier le contenu d'un pointeur de caractère dans une autre et cette fonction ne va pas le faire. Tout ce que vous faites est de sommer la valeur de chaque caractère dans charBuffer en newStr car un char est en fait un entier de 8 bits et vous renvoyez cet entier comme un pointeur à travers un cast implicite, donc il est maintenant traité comme une mémoire adresse.

Vous devriez chercher à utiliser strdup(), comme cela a été noté, puisque c'est exactement ce que la fonction est censée faire. Pas besoin de réinventer la roue. :)

3

Il pourrait y avoir plusieurs autres, mais voici quelques points sur ce qui ne va pas:

  1. Votre fonction newStr est juste très, très mal . Lors d'une supposition que vous voudriez quelque chose comme:

    char * newStr (char * charBuffer) 
    { 
        char *newStr; 
        if(charBuffer[0] == 'A' || charBuffer[0] == 'Q') { 
        newStr = strdup(&charBuffer[1]); 
        } else { 
        newStr = strdup(""); 
        } 
        if(newStr == NULL) { 
         //handle error 
        } 
        return newStr; 
    } 
    
  2. Vous ne pouvez pas lancer une chaîne en char comme vous le faites ici:

    if(ans[0] == (char)"Y" || ans[0] == (char)"y") 
    

    Do à la place (même pour un code similaire ailleurs aussi)

    if(ans[0] =='Y' || ans[0] == 'y') 
    
  3. comme ci-dessus lorsque vous appelez putc, ne le font pas

    fputc((char)"A", f); 
    

    Do

    fputc('A', f); 
    
  4. scanf a besoin d'une chaîne de format, ne pas faire:

    scanf(ans); 
    

    Do par exemple(Ou tout simplement utiliser fgets à nouveau)

    if(scanf("%99s",ans) != 1) { 
        //handle error 
    } 
    
Questions connexes