我在c中写了一个简单的银行应用程序 它将信息保存在文件中。 我想在每次运行应用程序时加载文件,并将文件中的信息添加到结构中,为此,我编写了两个函数,名为" loadfile"和"分配"
在函数" loadfile"如果我取消对评论行的评论,那么操作系统将停止工作"在我脸上:|
你可以帮帮我吗? 当我在" loadfile"中使用(acc + i)时,错误显示出来。 有语法问题吗? :○ 感谢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;
}
答案 0 :(得分:1)
发布的代码存在很多问题。目前还不清楚单独的分配函数如何有用,并且不建议使用文件范围变量acc
。我认为在这里使用realloc()
毫无意义,因为分配只进行一次。如果使用realloc()
,则应将结果存储在临时指针中,因为如果存在分配错误,该函数可以返回NULL
指针。如果直接指定要重新分配的指针,则会导致内存泄漏。我重写了代码来说明一些修复,试图维护原始代码的一般结构。
您应该检查您调用的函数的返回值。 realloc()
和malloc()
返回指向已分配内存的指针,或者在分配错误时返回NULL
指针。您应该检查此值并处理结果。 scanf()
函数返回成功分配的数量。您应该检查此值以验证输入是否符合预期。使用feof()
来控制循环是almost always a bad idea,因为此函数依赖于设置的文件结束指示符,并且仅在I / O操作失败时设置此指示符。
在下面的程序中,fgets()
用于从文件读取一行输入到缓冲区,sscanf()
用于从缓冲区中提取输入数据。在分配阶段,EOF
或空行表示数据的结束。此处不进行解析,只计算行数。对于每一行,为account
分配空间。请注意,代码会检查打开和关闭文件时的错误,以及分配错误。
loadfile()
函数再次使用fgets()
将输入行读入buffer
,然后使用sscanf()
扫描缓冲区。请注意字符串使用宽度说明符。它们比它们读入的数组大小少一个,为'\0'
放置在字符串末尾的sscanf()
留出空间。exit
。另请注意,如果进行的分配少于4次,则程序account
会显示错误消息。如果临时变量的分配成功,则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;
}
),但这应该为您提供一个良好的起点。
editActionsForRowAt
答案 1 :(得分:-1)
我无法解释你所有的问题。这需要几个小时。我希望这段代码能够自我描述。如果您需要帮助,请在评论中提问我。
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char name[20];
int id;
int balance;
char branch[10];
} account_t;
static account_t *parse_account_file(FILE *file, size_t *size) {
if (file == NULL || size == NULL) {
return NULL;
}
size_t i = 0;
account_t *account = malloc(sizeof *account);
if (account == NULL) {
return NULL;
}
int ret;
while (
(ret = fscanf(file, "%19s %d %d %9s\n", account[i].name, &account[i].id,
&account[i].balance, account[i].branch)) == 4) {
account_t *old = account;
account = realloc(account, sizeof *account * (++i + 1));
if (account == NULL) {
free(old);
return NULL;
}
}
if (ret == EOF) {
if (ferror(file)) {
perror("parse_account_file()");
} else {
*size = i;
account_t *old = account;
account = realloc(account, sizeof *account * i);
if (account == NULL) {
return old;
}
return account;
}
} else {
fprintf(stderr, "error parsing\n");
}
free(account);
return NULL;
}
int main(void) {
char const *name = "D:\\bank.txt";
FILE *file = stdin;
size_t size;
account_t *account = parse_account_file(file, &size);
fclose(file);
if (account == NULL) {
return 1;
}
for (size_t i = 0; i < size; i++) {
printf("%s %d %d %s\n", account[i].name, account[i].id, account[i].balance,
account[i].branch);
}
free(account);
}