【问题标题】:Parsing a file, and storing it into a BST解析文件,并将其存储到 BST
【发布时间】:2014-07-21 14:31:26
【问题描述】:

首先我知道这个程序有点长,但如果我不把它全部发布出来,你可能会感到困惑。基本上我需要读取大约 5 行文本的文件,使用 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) != NULL){

            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

【问题讨论】:

  • new_ 不是Command 结构,而是指向Command 结构的双指针。要访问成员,您需要执行(*new_)-&gt;name
  • 谢谢,我更改了我的插入函数,但我仍然遇到与类型不同有关的编译错误。我更新了原帖
  • @johnnyDepp 请更新您的代码,您问题中的代码仅反映旧错误
  • 你的create_commands_tree() 函数没有使用它的第一个参数,这将是一个问题。很遗憾,您的编译问题与未使用参数的类型有关。然后,当您调用它时,您将错误的类型传递给它。为了满足编译器的要求,请将insert_into_commands_tree((*new_)-&gt;left,data); 替换为insert_into_commands_tree(&amp;(*new_)-&gt;left, data);。与第 96 行类似。display_commands() 不使用其 node 参数; get_command() 需要返回一个值。
  • 我确实更新了我的代码。我更新了我的 insert_into_commands_tree 函数并更新了错误。您还需要更新其他内容吗?

标签: c string parsing binary-tree strtok


【解决方案1】:
Command **new_ = node;

这里的变量new_是一个指向指针的指针,你尝试这样使用ist

new_->name    

访问结构的名称成员。

您需要取消对它的引用以拥有一个Command*,您可以在其上使用-&gt; 运算符,这样做:

(*new_)->name;

【讨论】:

  • 谢谢这是有道理的,但我现在仍然遇到不同的编译错误。我用我所做的更改和新错误更新了我的帖子
  • insert_into_commands_tree 如果您打算将其分配给某物,则需要返回一个值。
  • 我想,既然原型以 void 开始,你就不能返回任何东西?
  • 我没有投反对票,但您的修复尚未完成,由于(*new_)-&gt;left = insert_into_commands_tree((*new_)-&gt;left, data); 分配,应用后仍然存在编译错误。
  • 哈,因为我知道它有很多问题!!感谢@A4L 的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
相关资源
最近更新 更多