如何遍历文本,将文件中的数据读入 c 中的多个变量?
How can I loop through text, reading data from a file into several variables in c?
我意识到这听起来像是一个重复的问题,它可能是,但我已经找了几天了。我搞砸的代码是这样的:
node* deSerialize(FILE *fp) {
char key[20];
char value[MAXSIZE];
node *n = NULL;
while (fscanf(fp, " %[^*]*%[^*]* ",key,value)==2) {
if (n) {
n = add_node(n,key,value);
}
else{
n = new_node(key,value);
}
}
return n;
}
但是当我将反序列化的结构保存回磁盘时,它只保存最后一个key/value。像这样:
test*value* test*value* test*value* test*value* test*value* test*value* test*value* test*value*
而序列化结构如下所示:
key1*value1* key2*value2* key3*value3* key4*value4* key5*value5* key6*value6* key7*value7* test*value*
我知道字符串指针(或数组指针,不知道真正叫什么)key
和 value
正在更新,因此它们最终都指向相同的东西,但我该如何防止呢?
为了完整起见,以下是其他涉及的函数:
void serialize(FILE *fp, node *n) {
node *j = n;
while (j) {
while(j->left) {
serialize(fp,j->left);
j->left=NULL;
}
while(j->right) {
serialize(fp,j->right);
j->right=NULL;
}
fprintf(fp,"%s*%s* ",j->key,j->value);
j=NULL;
}
}
node* new_node(char *key, char *value) {
struct node* result = malloc(sizeof(struct node));
memset(result, 0, sizeof(struct node));
result->key = key;
result->hash = hash(key);
result->value = value;
result->left = result->right = NULL;
return result;
}
node* add_node(node* tree, char *key, char *value ) {
unsigned long h = hash(key);
if (tree==NULL)
tree=new_node(key,value);
if (h<tree->hash)
tree->left = add_node(tree->left,key,value);
if (h>tree->hash)
tree->right = add_node(tree->right,key,value);
return tree;
}
But when I save the deserialized structure back to a disk, it only saves the last key/value.
您在循环中存储相同的变量,如果您事先不知道行数,则在每次迭代时用 malloc
保留。
More detail on dynamically allocating with malloc would still be
awesome though
像这样(未测试):
char *key;
char *value;
node *n = NULL;
while (1) {
key = malloc(20);
if (key == NULL) {
/* raise error */
}
value = malloc(MAX_SIZE);
if (value == NULL) {
/* raise error */
}
if (fscanf(fp, " %[^*]*%[^*]* ", key, value) != 2) {
free(key);
free(value);
break;
}
if (n) {
n = add_node(n, key, value);
} else {
n = new_node(key, value);
}
}
您必须 free
这些值(可能在 tree_destroy()
函数中)以避免内存泄漏。
您需要为结构中的重复字符串动态分配内存。目前,您覆盖了之前的数据,因为所有节点都引用同一个数组。
你不想创建一个二维数组,但是,因为在你的函数return上,你的节点将引用堆栈上的内存已经清理干净了。 (本地数组放在堆栈上,并在函数 returns 时被移除。)正确的方法是使用动态内存分配。
这是一种使用动态分配保存数据的方法:
node* new_node(char *key, char *value) {
struct node* result = malloc(sizeof(struct node));
memset(result, 0, sizeof(struct node));
result->key = strdup(key); //DUPLICATE STRING
result->hash = hash(key);
result->value = value;
result->left = result->right = NULL;
return result;
}
您不必事先知道字符串的大小。此外,您还需要 free()
通过实现 destroy_node()
函数分配的内存:
void destroy_node(node *n) {
if (n != NULL) {
free(n->key);
free(n);
}
}
我意识到这听起来像是一个重复的问题,它可能是,但我已经找了几天了。我搞砸的代码是这样的:
node* deSerialize(FILE *fp) {
char key[20];
char value[MAXSIZE];
node *n = NULL;
while (fscanf(fp, " %[^*]*%[^*]* ",key,value)==2) {
if (n) {
n = add_node(n,key,value);
}
else{
n = new_node(key,value);
}
}
return n;
}
但是当我将反序列化的结构保存回磁盘时,它只保存最后一个key/value。像这样:
test*value* test*value* test*value* test*value* test*value* test*value* test*value* test*value*
而序列化结构如下所示:
key1*value1* key2*value2* key3*value3* key4*value4* key5*value5* key6*value6* key7*value7* test*value*
我知道字符串指针(或数组指针,不知道真正叫什么)key
和 value
正在更新,因此它们最终都指向相同的东西,但我该如何防止呢?
为了完整起见,以下是其他涉及的函数:
void serialize(FILE *fp, node *n) {
node *j = n;
while (j) {
while(j->left) {
serialize(fp,j->left);
j->left=NULL;
}
while(j->right) {
serialize(fp,j->right);
j->right=NULL;
}
fprintf(fp,"%s*%s* ",j->key,j->value);
j=NULL;
}
}
node* new_node(char *key, char *value) {
struct node* result = malloc(sizeof(struct node));
memset(result, 0, sizeof(struct node));
result->key = key;
result->hash = hash(key);
result->value = value;
result->left = result->right = NULL;
return result;
}
node* add_node(node* tree, char *key, char *value ) {
unsigned long h = hash(key);
if (tree==NULL)
tree=new_node(key,value);
if (h<tree->hash)
tree->left = add_node(tree->left,key,value);
if (h>tree->hash)
tree->right = add_node(tree->right,key,value);
return tree;
}
But when I save the deserialized structure back to a disk, it only saves the last key/value.
您在循环中存储相同的变量,如果您事先不知道行数,则在每次迭代时用 malloc
保留。
More detail on dynamically allocating with malloc would still be awesome though
像这样(未测试):
char *key;
char *value;
node *n = NULL;
while (1) {
key = malloc(20);
if (key == NULL) {
/* raise error */
}
value = malloc(MAX_SIZE);
if (value == NULL) {
/* raise error */
}
if (fscanf(fp, " %[^*]*%[^*]* ", key, value) != 2) {
free(key);
free(value);
break;
}
if (n) {
n = add_node(n, key, value);
} else {
n = new_node(key, value);
}
}
您必须 free
这些值(可能在 tree_destroy()
函数中)以避免内存泄漏。
您需要为结构中的重复字符串动态分配内存。目前,您覆盖了之前的数据,因为所有节点都引用同一个数组。
你不想创建一个二维数组,但是,因为在你的函数return上,你的节点将引用堆栈上的内存已经清理干净了。 (本地数组放在堆栈上,并在函数 returns 时被移除。)正确的方法是使用动态内存分配。
这是一种使用动态分配保存数据的方法:
node* new_node(char *key, char *value) {
struct node* result = malloc(sizeof(struct node));
memset(result, 0, sizeof(struct node));
result->key = strdup(key); //DUPLICATE STRING
result->hash = hash(key);
result->value = value;
result->left = result->right = NULL;
return result;
}
您不必事先知道字符串的大小。此外,您还需要 free()
通过实现 destroy_node()
函数分配的内存:
void destroy_node(node *n) {
if (n != NULL) {
free(n->key);
free(n);
}
}