我正在尝试从文件中读取已保存的数据。我试图将缓冲区中的信息从字符串转换为字符,并将其值分配给结构的成员。 似乎数据未被正确访问,当我打印出节点值时,它与文件中的内容不同。我不知道我哪里出错了。
文件格式:
3 2 43 4
2 4 5 6
$Node
4
1 0 -1 0
2 0 1 0
3 10 -1 0
4 10 1 0
$EndNodes
$Elements
2
1 2 3 4
2 3 5 6
$EndElements
代码:
struct Node {
int x; // position
int y; //position
int z; //position
int total_node_nums; // total node numbers
};
struct Element{
int total_elmt_num; // total element numbers
struct Node *node; // array of nodes
};
来自main的电话:
void arr_creator(char *fname, char *str_start, char *str_end);
arr_creator:
void arr_creator(char *fname, char *str_start, char *str_end){
FILE *fl_read;
char buffer[512], line_buff[20];
int i,num_node,tag,line = 0;
fl_read = fopen(fname, "r");
if(fl_read == NULL){
printf("\n[error reading file] :: in function arr_creator\n");
return;
}
// Scan file for str_start
while(fgets(buffer, sizeof(buffer),fl_read) != NULL ) {
if(strstr(buffer,str_start)){
printf("\nline: %d string: %s \n",line+1, str_start);
fgets(buffer,sizeof(buffer),fl_read);
num_node = atoi(buffer);
printf("num_node = %d\n", num_node);
struct Node *node;
node = malloc((num_node+1)*sizeof(node));
for(i=1; i<num_node+1;i++){
sscanf(buffer,"%d %d %d %d", &tag, &node[i].x, &node[i].y, &node[i].z);
printf("--------------\n");
printf(" Node %d \n", tag);
printf("--------------\n");
printf("node[%d].x = %d\n",i, node[i].x);
printf("node[%d].y = %d\n",i, node[i].y);
printf("node[%d].z = %d\n",i, node[i].z);
printf("BUFFER :: %s", buffer);
}
}
line++;
if(strstr(buffer,str_end)){
printf("buffer at break :: %s", buffer);
// buffer[0] = '\0';
break;
}
}
if(fl_read){
fclose(fl_read);
}
}
答案 0 :(得分:1)
您需要在fgets
循环中再次呼叫for
。你只是一遍又一遍地读取相同的缓冲区内容。它仍然是第一行,只有一个数字。
答案 1 :(得分:1)
您没有正确分配内存。我指的是这四行,虽然最后一个是主要罪犯,其他人也不太好。通过分配少于所需空间来存储struct Node
,当您尝试访问超出分配区域时,您将调用未定义的行为。
num_node = atoi(buffer);
printf("num_node = %d\n", num_node);
struct Node *node;
node = malloc((num_node+1)*sizeof(node));
node
是一个指针。你期望指针的大小是什么?它可能不是你想要的那样。
这很愚蠢,使用int
来确定要分配的对象数。如果有人输入负数怎么办?记下我如何处理sscanf
返回值。有一天,它可能会拯救你。您可以在opengroup scanf manual中详细了解相关内容(请记住“opengroup scanf手册”,以便了解google的内容)。
size_t num_node; /* Suggestion: USE A SIZE TYPE! It's what they're for. */
assert(sscanf(buffer, "%zu", &num_node) == 1);
printf("num_node = %zu\n", num_node);
struct Node *node;
node = malloc((num_node+1) * sizeof *node);
*node
不是指针;这是一个实际的对象。你想根据对象的大小来分配,对吗?
我认为,通过文件格式的外观,行数与每个node
分开。在尝试解析之前,你需要先尝试另一行,在这种情况下:
/* TODO: Handle read errors, rather than just `assert`ing that the read succeeds */
assert(fgets(buffer,sizeof buffer,fl_read) == buffer)
/* TODO: Handle parsing errors, rather than just `assert`ing that the parsing succeeds */
assert(sscanf(buffer,"%d %d %d %d", &tag, &node[i].x, &node[i].y, &node[i].z) == 4)
答案 2 :(得分:0)
重写您的代码,如下所述
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int tag;
int x; //position
int y; //position
int z; //position
};
struct Nodes {
int total_node_num;
struct Node *nodes;//array of node
};
struct Nodes *arr_creator(char *fname, char *str_start, char *str_end){
FILE *fl_read;
char buffer[512];
int line = 0;
fl_read = fopen(fname, "r");
if(fl_read == NULL){
printf("\n[error reading file] :: in function arr_creator\n");
return NULL;
}
while(fgets(buffer, sizeof(buffer),fl_read) != NULL ) {
++line;
if(strstr(buffer, str_start)){
int i, num_node;//work
struct Node *node;//work
printf("\nline: %d string: %s \n", line, str_start);
struct Nodes *nodes = malloc(sizeof(struct Nodes));
num_node = nodes->total_node_num = atoi(fgets(buffer,sizeof(buffer),fl_read));
printf("num_node = %d\n", num_node);
node = nodes->nodes = malloc(num_node*sizeof(struct Node));
for(i=0;;i++){
fgets(buffer,sizeof(buffer),fl_read);
if(strstr(buffer, str_end)){
if(i == num_node){
printf("buffer at break :: %s", buffer);
} else if(i < num_node){
fprintf(stderr, "The number of nodes less than the specified!");
nodes->total_node_num = i;
}
fclose(fl_read);
return nodes;
} else if(i >= num_node){
fprintf(stderr, "The number of nodes more than the specified!\n"
"*read only the number of specified.*");
fclose(fl_read);
return nodes;
}
//read node check print
sscanf(buffer," %d %d %d %d ", &node[i].tag, &node[i].x, &node[i].y, &node[i].z);
printf("--------------\n");
printf(" Node %d \n", node[i].tag);
printf("--------------\n");
printf("node[%d].x = %d\n",i, node[i].x);
printf("node[%d].y = %d\n",i, node[i].y);
printf("node[%d].z = %d\n",i, node[i].z);
printf("BUFFER :: %s", buffer);
}
}
}
fclose(fl_read);
return NULL;
}
int main(void) {
struct Nodes *nodes;
struct Node *node;
int i;
nodes=arr_creator("data.txt", "$Node", "$EndNodes");
node = nodes->nodes;
for(i=0;i<nodes->total_node_num;++i){
printf("\n Node %d \n", node[i].tag);
printf("--------------\n");
printf("node[%d].x = %d\n",i, node[i].x);
printf("node[%d].y = %d\n",i, node[i].y);
printf("node[%d].z = %d\n",i, node[i].z);
}
return 0;
}