-1

我正在尝试从文件中读取保存的数据。我正在尝试将缓冲区中的信息从字符串转换为字符,并将它们的值分配给结构的成员。似乎数据没有被正确访问,当我打印出节点值时,它与文件中存储的不同。我看不出哪里出错了。

文件格式:

    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); 
     }
}
4

3 回答 3

1

您需要在循环中fgets 再次调用。for您只是一遍又一遍地读取相同的缓冲区内容。它仍然是第一行,里面只有一个数字。

于 2013-04-27T02:22:25.910 回答
1

您没有正确分配内存。我指的是这四行,虽然最后是主要的罪犯,其他的也不太好。通过分配少于存储所需的空间 a struct Node,当您尝试访问分配的区域之外时,您将调用未定义的行为。

num_node = atoi(buffer); 
printf("num_node = %d\n", num_node); 
struct Node *node; 
node = malloc((num_node+1)*sizeof(node)); 

node是一个指针。你期望指针的大小是多少?这可能不是你想要的。

这是相当愚蠢的,使用 anint来确定要分配多少对象。如果有人输入负数怎么办?请注意我如何处理sscanf返回值。有一天,它可能会拯救你。您可以在opengroup scanf 手册中阅读更多相关信息(请记住“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. 在尝试解析之前,您需要 fgets 另一行,在这种情况下:

/* 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)
于 2013-04-27T02:22:59.020 回答
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;
}
于 2013-04-27T08:33:11.257 回答