解析读入文件并存储在b树中

时间:2014-07-21 17:37:42

标签: c parsing segmentation-fault binary-tree

我非常确定我的程序会永远运行,因为当我运行程序时,不会产生任何输出,甚至不会产生分段错误。基本上我想让我的程序做的是在4行文件中读取。然后我们使用用户创建的tokenizer函数和已经创建的strtok函数来解析字符串。然后我想从读入的命令中创建一个二叉树。就像我之前说的那样,我的程序当时没有产生输出,但它确实编译了。我将发布我拥有的代码和您读入的文件以及示例输出。我很感激帮助。

#include<stdlib.h>
#include<string.h>
#include<stdio.h>

#define COMMAND_NAME_LEN 50
#define MAX_SPLIT_SIZE 50
#define MAX_BUFF_SIZE 50

typedef struct Command_ {
    char name[COMMAND_NAME_LEN];
    int expected_param_count;
    struct Command_ *left;
    struct Command_ *right;
}Command;


typedef struct StringArray_ {
    char **strings;
    int size;
}StringArray;

StringArray* tokenizer (char *string, const char* delimiters);
void free_string_array(StringArray *sr);
void create_commands_tree(Command **commands, const char *file);
void insert_into_commands_tree(Command** node, char** data);
Command* get_command(Command *node, const char *command);
Command* create_command(char **data);
void destroy_commands_tree(Command* node);
void display_commands(Command *node);


int main (int argc, char *argv[]) {

    if (argc < 2) {
            printf("%s is missing commands.dat\n", argv[0]);
            return 0;
    }


    Command* options = NULL;
    create_commands_tree(&options,argv[1]);
    int checking = 1;

    char input_buffer[MAX_BUFF_SIZE];

    do {
            printf("Command: ");
            fgets(input_buffer,MAX_BUFF_SIZE,stdin);
            StringArray* parsed_input = tokenizer(input_buffer," \n");
            Command* c = get_command(options,parsed_input->strings[0]);

            if( c && parsed_input->size == c->expected_param_count) {
                    if (strcmp(c->name, "quit") == 0){
                                    checking = 0;
                    }
                    printf("Valid command used\n");
            }
            else {
                    printf("Invalid command, please try again\n");
            }
            free_string_array(parsed_input);

    }while (checking);

    destroy_commands_tree(options);

}


void create_commands_tree(Command **commands, const char *file) {

    FILE *input;
    input = fopen(file, "r");
    char strings[256];
    Command *temp;
    StringArray *temp2;

    while(fgets(strings,100,input)){

            temp2 = tokenizer(strings, "\n");
            insert_into_commands_tree(&temp,temp2->strings);
    }
}

void insert_into_commands_tree(Command** node, char** data) {

    Command **new_ = node;

    if(node == NULL){
            *new_ = create_command(data);
    }
    else if( new_ != NULL){
            if(strcmp(data[0],(*new_)->name) < 0)
                    insert_into_commands_tree(&(*new_)->left,data);
            else if(strcmp(data[0], (*new_)->name) > 0)
                    insert_into_commands_tree(&(*new_)->right,data);
    }


}

Command* create_command(char **data) {

    Command* new_;
    new_ = (Command*)malloc(sizeof(Command));
    strncpy(new_->name, data[0], COMMAND_NAME_LEN);
    new_->expected_param_count = 0;
    new_->right = NULL;
    new_->left = NULL;


    return new_;

}

Command* get_command(Command *node, const char *command) {

    Command *temp = node;
    int compare;

    if(temp){
            compare = strcmp(node->name, command);
            if(compare == 0){
                    return temp;
            }
            else if(compare < 0){
                    return (get_command(node->right, command));
            }
            else{
                    if(compare > 0){
                            return (get_command(node->left, command));
            }}

    }
   return temp;
}

void destroy_commands_tree(Command* node) {

    if( node == NULL){
            return;
            }

    destroy_commands_tree(node->left);
    destroy_commands_tree(node->right);
    free(node);

}
void display_commands(Command *node) {

      if(node != NULL){
            printf("\npickup <item>");
            printf("\nhelp ");
            printf("\nquit ");
            printf("\nload <file>\n\n");
}
}
 StringArray* tokenizer (char *string, const char* delimiters){

    StringArray *temp = (StringArray*)malloc(sizeof(StringArray));;
    char *split;

    split = strtok(string, delimiters);

    while(split != NULL)
    {
            split = strtok(string, delimiters);
            temp->strings = &split;
    }
    return temp;
}

void free_string_array(StringArray *sr) {

    while(sr != NULL)
            free(sr);

    free(sr);

}

以下是给出的示例输出:

]$ ./a.out commands.dat 
Command: pickup 
Invalid command, please try again 
Command: pickup ball 
Valid command used 
Command: quit 1 
Invalid command, please try again 
Command: load 
Invalid command, please try again 
Command: load bak.sav 
Valid command used 
Command: help
Valid command used
Command: help 2 
Invalid command, please try again 
Command: quit 
Valid command used 

我们读到的文件如下:

pickup,2
help,1
quit,1
load,2

1 个答案:

答案 0 :(得分:0)

来自strtok联机帮助页:

   The strtok() function breaks a string into a sequence of zero or more nonempty tokens.  On the
   first call to strtok() the string to be parsed should be specified in str.  In each subsequent
   call that should parse the same string, str must be NULL.

您的tokenizer未正确使用strtok。你的代码卡在了while循环中。