【问题标题】:Parsing a read in file and storing in a b tree解析读入文件并存储在b树中
【发布时间】:2014-09-12 07:45:31
【问题描述】:

我很确定我的程序会永远运行,因为当我运行程序时不会产生任何输出,甚至不会产生分段错误。基本上我希望我的程序做的是读入一个 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

【问题讨论】:

  • 您可能会考虑尝试改进您的原始问题,而不是尝试重新发布它。
  • 没有人回复我的旧的,有人回复了这个并帮助了我,所以我说这是值得的
  • 虽然您可能觉得这一次是个好主意,但这并不是一个好的模式。您可以通读this post 以了解尝试引起对您问题的关注的正确方法。最好的方法是首先提出一个好问题。帮助中心有很多关于这方面的建议。

标签: c parsing segmentation-fault binary-tree


【解决方案1】:

来自 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.

您的分词器未正确使用 strtok。您的代码卡在 while 循环中。

【讨论】:

  • 非常感谢您的帮助
猜你喜欢
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2015-08-01
  • 2015-10-13
  • 2018-01-01
  • 1970-01-01
相关资源
最近更新 更多