简体   繁体   English

我可以使用自己的内存分配char指针吗?

[英]Can I allocate a char pointer with own memory?

I'm in the second semester of my college so I just started coding. 我正在上大学的第二学期,所以我才开始编码。 Recently we learned something about binary trees. 最近,我们了解了有关二叉树的一些知识。 So I just wanted to code my own ones. 所以我只想编写自己的代码。 I decided to code a binary tree contact book. 我决定编写一本二叉树通讯录。

First I'm saving my struct into a .txt file. 首先,我将结构保存到.txt文件中。 (I want it in a txt file, not a binary, because then i can read it after the program.) After that I try to load it again in a node to rebuild my binary tree. (我希望将其保存在txt文件中,而不是二进制文件中,因为这样我可以在程序之后读取它。)之后,我尝试再次将其加载到节点中以重建二进制树。

Here we go with a shortened version. 在这里,我们用一个简化的版本。 I commented the important parts. 我评论了重要部分。

#define CLEN 100

struct binarytree {
    struct binarytree *left;
    struct binarytree *right;
    char *firstname;
    char *lastname;
    char *city;
    char *street;
    char *addr;
    char *tel;
} typedef btree;

//-----------------------------------------

btree *creatnullnode(void);
btree *loadtree(char *filename);

//-----------------------------------------

btree *creatnullnode(void) {
    btree *node = malloc(sizeof(btree));
    node->left  = NULL;
    node->right = NULL;

    //TODO: the memmory is not right allocated..
    node->firstname = (char*)malloc(CLEN * sizeof(char));
    node->lastname  = (char*)malloc(CLEN * sizeof(char));
    node->city      = (char*)malloc(CLEN * sizeof(char)); 
    node->street    = (char*)malloc(CLEN * sizeof(char));
    node->addr      = (char*)malloc(CLEN * sizeof(char));
    node->tel       = (char*)malloc(CLEN * sizeof(char));
    return node;
}

btree *loadtree(char *filename) {
    FILE *fp;
    btree *tree = NULL;
    btree *node = creatnullnode();
    char ch = "";
    int lines = 0;

    fp = fopen(filename,"r");
    if (!fp) {
        printf("Error. no file\n");
        return NULL;
    } else {
        while (!feof(fp)) {
            ch = fgetc(fp);
            if (ch == '\n')
                lines++;
        }
        fseek(fp, 0,(int)lines % 2);

        //TODO: right here the memory of every char can't be read anymore
        fscanf(fp, "%s\t\t%s\t\t\t%s\t%s\t\t%s\t\t%s\n",
               &node->firstname, &node->lastname, &node->addr, &node->city, 
               &node->street, &node->tel);

        tree = insertnode(tree, node);

        fseek(fp, 0, 0);
        //rekursiveload(&tree, fp);      //TODO: - ausprogrammieren -
    }

    fclose(fp);
    return tree;
}

While debugging I saw that the memory did not get correctly allocated. 调试时,我发现内存分配不正确。 But i don't know how to fix it. 但是我不知道如何解决它。

after allocationg the char[] is set to: node->firstname = 0x007db250 "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýýM¸Þµ¦æ" Debugger says: <Error reading the characters of the string.> after fscanf allocationg炭后[]被设定为: node->firstname = 0x007db250 "ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýýM¸Þµ¦æ"调试器说: <Error reading the characters of the string.>fscanf

There are several issues in your code: 您的代码中存在几个问题:

  • while (!feof(fp)) is always wrong for testing end of file: Why is “while (!feof(file))” always wrong? while (!feof(fp))对于测试文件结尾总是错误的: 为什么“ while(!feof(file))”总是错误的? You should instead write this: 您应该这样写:

      while ((ch = fgetc(fp)) != EOF) { ... 
  • you should create a new node for each line that you read from the file. 您应该为从文件中读取的每一行创建一个新节点。 Currently you reuse the same memory for each node and overwrite the fields with the new data. 当前,您为每个节点重复使用相同的内存,并使用新数据覆盖字段。 insertnode , which is missing from the code fragment, most probably creates a loop in the list, causing undefined behavior when you try and free it. 代码片段中缺少的insertnode ,很可能在列表中创建了一个循环,当您尝试释放它时会导致未定义的行为。

  • char ch = ""; is incorrect: "" is a string, not a char , and ch must be defined as an int to read bytes with fgetc() and store EOF too. 是错误的: ""是字符串,而不是char ,并且ch必须定义为int才能使用fgetc()读取字节并存储EOF

  • fseek(fp, 0,(int)lines % 2); is meaningless. 是没有意义的。 What are you trying to achieve? 您想达到什么目的? you can try and rewind the stream with rewind(fp) or fseek(fp, 0L, SEEK_SET) , but you will only be able to read a single line . 您可以尝试使用rewind(fp)fseek(fp, 0L, SEEK_SET)倒带流,但是您只能读取一行。

  • fscanf(fp, "%s\\t\\t%s\\t\\t\\t%s\\t%s\\t\\t%s\\t\\t%s\\n", &node->firstname, ... has multiple issues: you cannot prevent incorrect input from causing too many characters to be stored into the destination arrays, and you should pass pointers to the destination arrays, not addresses of pointers. In other words, the code should be: fscanf(fp, "%s\\t\\t%s\\t\\t\\t%s\\t%s\\t\\t%s\\t\\t%s\\n", &node->firstname, ...具有多个问题:您不能防止错误输入导致太多字符存储到目标数组中,应该将指针传递给目标数组,而不是指针地址,换句话说,代码应为:

      char eol; if (fscanf(fp, "%99s%99s%99s%99s%99s%99s%c", node->firstname, node->lastname, node->addr, node->city, node->street, node->tel, &eol) != 7 || eol != '\\n') { /* invalid input... */ } 

    A much safer approach to read this input is to read a single line into a larger array of char and use sscanf() to parse this line into the node fields... but looking at your format string, it seems you are dealing with TAB separated values and 读取此输入的一种更安全的方法是将一行读取到较大的char数组中,并使用sscanf()将这一行解析为node字段...但是查看您的格式字符串,似乎您正在处理TAB分隔值和

  • Neither fscanf() , nor sscanf() nor even strtok() can properly parse TAB separated values from a text file. fscanf()sscanf()甚至strtok()都无法正确解析文本文件中的TAB分隔值。 You need to write you own code for this. 您需要为此编写自己的代码。 I suggest you use strcspn() to compute the field lengths and strndup() to allocate strings from a range in a char array. 我建议您使用strcspn()计算字段长度,并使用strndup()char数组中的某个范围分配字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM