Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 解析读入文件并将其存储在二叉树中_C_Parsing_Segmentation Fault_Binary Tree - Fatal编程技术网

C 解析读入文件并将其存储在二叉树中

C 解析读入文件并将其存储在二叉树中,c,parsing,segmentation-fault,binary-tree,C,Parsing,Segmentation Fault,Binary Tree,当我尝试将节点插入二叉树时,我遇到了一个SEGFULT。我用gdb运行程序,下面是我发现的关于segfault的内容,但我不知道在我的insert和create函数中要更改什么。提前谢谢你的帮助 Program received signal SIGSEGV, Segmentation fault. __strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp.S:260 260 movdqu (%rsi), %xmm2 (gdb) w

当我尝试将节点插入二叉树时,我遇到了一个SEGFULT。我用gdb运行程序,下面是我发现的关于segfault的内容,但我不知道在我的insert和create函数中要更改什么。提前谢谢你的帮助

Program received signal SIGSEGV, Segmentation fault.
__strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp.S:260
260     movdqu  (%rsi), %xmm2
(gdb) where
#0  __strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp.S:260
#1  0x0000000000400a42 in insert_into_commands_tree (node=0x7fffffffe0b0, 
data=0x602270) at lab8.c:116
#2  0x00000000004009d7 in create_commands_tree (commands=0x7fffffffe0b0, 
file=0x7fffffffe4a1 "commands.dat") at lab8.c:104
#3  0x0000000000400835 in main (argc=2, argv=0x7fffffffe1b8) at lab8.c:48
我的程序所做的是读取文本文件并解析字符串,然后将它们存储到二叉树中。然后用户键入一个命令,我搜索树,看看该命令是否在树中列出。我将发布我的完整代码,以便大家都能看到它,然后发布我读入的文件和示例输出,希望有人能帮助我解决这个segfault错误。先谢谢你。我的老师也为我们提供了main和tokenizer函数

#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[100];
    StringArray *temp2;

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

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

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

    if(*node == NULL){
            *node = create_command(data);
    }
    else if( *node != NULL){
            if(strcmp(data[0],(*node)->name) < 0)
                    insert_into_commands_tree(&(*node)->left,data);
            else if(strcmp(data[0], (*node)->name) > 0)
                    insert_into_commands_tree(&(*node)->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 = atoi(data[1]);
    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) {


            printf("\npickup <item>");
            printf("\nhelp ");
            printf("\nquit ");
            printf("\nload <file>\n\n");

}
 StringArray* tokenizer (char *string, const char* delimiters){

    StringArray* sr = malloc(sizeof(StringArray));
    sr->strings = malloc(MAX_SPLIT_SIZE * sizeof(char *));

    size_t len;
    char* hold;

    (sr->strings)[0] = malloc(MAX_BUFF_SIZE * sizeof(char));
    hold = strtok(string, delimiters);
    int i;
    for(i = 1; i < MAX_SPLIT_SIZE; i++){

            hold = strtok(NULL, delimiters);
            if(hold == NULL){
                    sr->size = i + 1;
                    break;
            }
            (sr->strings)[i] = malloc(MAX_BUFF_SIZE * sizeof(char));
            strcpy((sr->strings)[i], hold);
    }
    return sr;
}

void free_string_array(StringArray *sr) {

     int i;
    for(i = 0; i < sr->size; ++i){
             free(sr->strings[i]);
    }
            free(sr->strings);
            free(sr);
}
我们读到的文件如下:

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

此代码有几个问题:

在函数中,将\u插入到\u命令树中 就像上面的评论中所说的,条件应该是if*node==NULL。这可能是导致SEG故障的原因

此外,如果。。。否则,如果结构在这里有点冗余,因为它是真/假条件。您可以简单地使用:

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

    if(*node == NULL) {
        *node = create_command(data);
    }
    else {
        if(strcmp(data[0],(*node)->name) < 0)
                insert_into_commands_tree(&(*node)->left,data);
        else if(strcmp(data[0], (*node)->name) > 0)
                insert_into_commands_tree(&(*node)->right,data);
    }
}
函数内标记器 这个函数的输出不是它应该的。这里的主要问题是没有将第一个令牌复制到StringArray中。下面是一个有效且稍微简化的标记器函数:

StringArray* tokenizer (char *string, const char* delimiters)
{
    StringArray* sr = malloc(sizeof(StringArray));
    sr->strings = malloc(MAX_SPLIT_SIZE * sizeof(char *));

    char* hold;
    int i = 0;

    hold = strtok(string, delimiters);
    while ((hold != NULL) && (i < MAX_SPLIT_SIZE))
    {
        (sr->strings)[i] = malloc(MAX_BUFF_SIZE * sizeof(char));
        strncpy((sr->strings)[i], hold, MAX_SPLIT_SIZE);
        i++;
        hold = strtok(NULL, delimiters);
    }

    sr->size = i;
    return sr;
}

通过这些修改,您的代码似乎达到了预期效果。

您已经是第三次问这个问题了。我仍然不知道解析读入文件意味着什么。这只是没有意义。在insert_into_命令树中使用strtok functionnode==NULL将我读入的文件拆分为令牌:错误。可能是节点->*节点,还是第一个?if*node==NULL和if*node!=空?在标记器处:放弃保留第一个标记。temp2=标记字符串,\n;在创建命令树时:\n应该是\n。
temp2 = tokenizer(strings, ",");
StringArray* tokenizer (char *string, const char* delimiters)
{
    StringArray* sr = malloc(sizeof(StringArray));
    sr->strings = malloc(MAX_SPLIT_SIZE * sizeof(char *));

    char* hold;
    int i = 0;

    hold = strtok(string, delimiters);
    while ((hold != NULL) && (i < MAX_SPLIT_SIZE))
    {
        (sr->strings)[i] = malloc(MAX_BUFF_SIZE * sizeof(char));
        strncpy((sr->strings)[i], hold, MAX_SPLIT_SIZE);
        i++;
        hold = strtok(NULL, delimiters);
    }

    sr->size = i;
    return sr;
}