Ошибка сегмента в дереве знаний - PullRequest
0 голосов
/ 30 июля 2010

Я реализую дерево знаний в c, которое может читать из файла. Я получаю ошибку seg в моей функции newStr. Я не могу проверить остальную часть моего кода с этой проблемой. У меня нет большого опыта работы с ц. Любая помощь будет принята с благодарностью.

мой .c файл #включают #включают #include "animal.h" #включают # Включают

/*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;
}

.h файл # Включают

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 ]

3 голосов
/ 30 июля 2010

Может быть еще несколько, но вот некоторые моменты о том, что не так:

  1. Ваша функция newStr просто очень, очень неправильная.В предположении, вы захотите что-то вроде:

    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. Вы не можете привести строку к символу, как здесь:

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

    Doвместо этого (то же самое для аналогичного кода в другом месте)

     if(ans[0] =='Y' || ans[0] == 'y')
    
  3. То же, что и выше, когда вы вызываете putc, не делайте

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

    Do

     fputc('A', f);
    
  4. scanf нужна строка формата, не делайте:

    scanf(ans);
    

    Делайте, например (или просто используйте fgets снова)

    if(scanf("%99s",ans) != 1) {
       //handle error
     }
    
1 голос
/ 30 июля 2010
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");
}

Ну, здесь есть несколько интересных вещей ... Чтобы перейти к медным трюкам, вы пытаетесь скопировать содержимое указателя символа в другой, и эта функция не собирается этого делать.Все, что вы на самом деле делаете, это суммируете значение каждого символа в charBuffer в newStr, потому что символ на самом деле является просто 8-битным целым числом, а затем вы возвращаете это целое как указатель через неявное приведение, так что теперь оно обрабатывается как памятьaddress.

Вы должны использовать strdup (), как уже было отмечено, поскольку это именно то, что должна делать функция.Не нужно изобретать велосипед.:)

0 голосов
/ 30 июля 2010

Оператор "+", так как конкатенация строк не работает в c.

Если вы действительно хотите скопировать строку, используйте strdup().Эта функция выделяет память и копирует в нее строку.

Не забудьте освободить выделенную память, когда закончите с ее использованием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...