我非常确定我的程序会永远运行,因为当我运行程序时,不会产生任何输出,甚至不会产生分段错误。基本上我想让我的程序做的是在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
答案 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循环中。