c - 这个错误是关于什么的?结构体、指针、动态内存分配,C

标签 c file struct allocation scanf

我正在用 c 语言编写一个简单的银行应用程序 它将信息保存在文件中。 我想在每次应用程序运行时加载文件,并将文件中的信息添加到结构中,为此,我编写了两个名为“loadfile”和“allocate”的函数

在函数“loadfile”中,如果我取消注释行,操作系统会在我脸上抛出“停止工作”:|

你能帮我吗? 当我在“loadfile”中使用 (acc+i) 时,出现错误。 是不是有语法问题? :o 谢谢

typedef struct {
    char name[20];
    int id;
    int balance;
    char branch[10];
} account;

account *acc;

int allocate ( account *acc )  {
    int num = 0 ;
    char tempname[20],tempbranch[10];
    int tempid = -1 ,tempbalance;
    FILE *file;
    file = fopen("D://bank.txt","r");
    while ( !feof(file) ) {
        fscanf(file,"%s %d %d %s ",tempname, &tempid, &tempbalance, tempbranch);
        if (tempid != -1)
            num++;
    }
    acc = ( account *) realloc ( acc, num * sizeof(account) );
    fclose(file);
    printf(" num in allocate function : %d",num);
    return num;
}

int loadfile (account *acc) {
    int num = allocate(acc);
    char tempname[20],tempbranch[10];
    int tempid ,tempbalance;
    if ( num != 0 ) {
        int i = 0 ;
        FILE *file;
        file = fopen("D:\\bank.txt","r+");
        for ( i = 0 ; !feof(file) && i < num ; i++ ) {
            fscanf(file,"%s ",tempname );
            fscanf(file,"%d ",&tempid );
            fscanf(file,"%d ",&tempbalance );
            fscanf(file,"%s ",tempbranch );
            printf("\n i is %d \n",i);
            /* strcpy( ((acc+i)->name) , tempname);
            (acc+i)->id = tempid;
            (acc+i)->balance = tempbalance;
            strcpy( ((acc+i)->branch) , tempbranch); */
        }
        fclose(file);
    }
    return num;
}

最佳答案

发布的代码存在很多问题。目前尚不清楚单独的分配函数有何帮助,并且不建议使用文件范围变量 acc 。我认为在这里使用 realloc() 没有意义,因为分配只完成一次。如果您确实使用 realloc(),则应将结果存储在临时指针中,因为如果出现分配错误,该函数可能会返回 NULL 指针。如果直接分配给要从中重新分配的指针,这会导致内存泄漏。我重写了代码来说明一些修复,试图保持原始代码的总体结构。

您应该检查您调用的函数的返回值。 realloc()malloc() 返回指向已分配内存的指针,或者在发生分配错误时返回 NULL 指针。您应该检查该值并处理结果。 scanf() 函数返回成功分配的数量。您应该检查该值以验证输入是否符合预期。是almost always a bad idea使用 feof() 控制循环,因为该函数依赖于设置的文件结束指示符,并且仅当 I/O 操作失败时才会设置该指示符。

在下面的程序中,fgets() 用于从文件中读取一行输入到缓冲区,sscanf() 用于提取输入来自缓冲区的数据。在分配阶段,EOF 或空行表示数据结束。这里没有进行解析,只是计算行数。对于每一行,都会为一个帐户分配空间。请注意,代码会检查打开和关闭文件时的错误以及分配错误。

loadfile() 函数再次使用 fgets() 将一行输入读取到 buffer 中,然后使用 sscanf () 扫描缓冲区。请注意字符串宽度说明符的使用。这些比它们读入的数组的大小小 1,以便为 sscanf() 放置在字符串末尾的 '\0' 留出空间。另请注意,如果进行的分配少于 4 次,则程序退出并显示错误消息。如果对临时变量的分配成功,则帐户将使用数据进行更新。

可以通过多种方式改进此代码(最明显的是通过删除全局变量 acc),但这应该为您提供一个良好的起点。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[20];
    int id;
    int balance;
    char branch[10];
} account;

account *acc = NULL;

int allocate(void)
{
    int num = 0 ;
    char buffer[1000];
    FILE *file;

    file = fopen("D://bank.txt","r");
    if (file == NULL) {
        fprintf(stderr, "Unable to open file in allocate()\n");
        exit(EXIT_FAILURE);
    }

    while (fgets(buffer, sizeof(buffer), file) != NULL &&
           buffer[0] != '\n') {
        num++;
    }

    acc = malloc(num * sizeof(*acc));
    if (acc == NULL) {
        fprintf(stderr, "Allocation error in allocate()\n");
        exit(EXIT_FAILURE);
    }

    if (fclose(file) != 0) {
        fprintf(stderr, "Unable to close file in allocate()\n");
        exit(EXIT_FAILURE);
    }

    printf(" num in allocate function : %d\n",num);
    return num;
}

int loadfile(void)
{
    int num = allocate();
    char buffer[1000], tempname[20],tempbranch[10];
    int tempid ,tempbalance;
    if ( num != 0 ) {
        int i = 0 ;
        FILE *file;

        file = fopen("D://bank.txt","r+");
        if (file == NULL) {
            fprintf(stderr, "Unable to open file in loadfile()\n");
            exit(EXIT_FAILURE);
        }

        while (fgets(buffer, sizeof(buffer), file) != NULL
               && buffer[0] != '\n') {
            if (sscanf(buffer, "%19s %d %d %9s",
                       tempname, &tempid, &tempbalance, tempbranch) != 4) {
                fprintf(stderr, "%d: Malformed input data\n", i);
                exit(EXIT_FAILURE);
            }

            strcpy(acc[i].name, tempname);
            acc[i].id = tempid;
            acc[i].balance = tempbalance;
            strcpy(acc[i].branch, tempbranch);
            ++i;
        }

        if (fclose(file) != 0) {
            fprintf(stderr, "Unable to open file in loadfile()\n");
            exit(EXIT_FAILURE);
        }
    }

    return num;
}

int main(void)
{
    int num = loadfile();
    for (int i = 0; i < num; i++) {
        printf("%s %d %d %s\n",
               acc[i].name, acc[i].id, acc[i].balance, acc[i].branch);
    }

    return 0;
}

关于c - 这个错误是关于什么的?结构体、指针、动态内存分配,C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41297133/

相关文章:

用 C 创建一个简单的配置文件和解析器

c - 在嵌入式目标上FLASH的m_text内存区域中保留内存空间

java - 如何在不将文件保存到磁盘的情况下打开文件

python - Python 中未指定的字节长度

c - Openssl 中 RSA 结构的大小和公钥的大小

c++ - 从终端发送 C++ 输入一行

c - 比较 C 中两个字符串的问题(段错误)核心转储

c - 将列表传输到类(class)

file - 如何删除文本文件中每行的前 x 个字符?

javascript - JQuery AJAX 从文件夹中向后读取文件