我想创建一个数据库类型,它将一个包含5000个名称和5000个相应工资的列表存储到一个数组中,由于控制台崩溃或编译器给我以下错误,我根本无法找到问题:“不能将'char *()[30]'转换为'char '以将参数'1'转换为'char *'fgets(char *,int,* FILE)“。
编辑:我在代码中改变了我能想到的任何东西,而且我似乎遇到了问题 特别是这一行:person* TAB = calloc(N, sizeof(struct));
我无法发现其他错误(缺乏经验),而且我不确切知道要使用什么而不是fgets来排队。
#include <stdio.h>
#include <stdlib.h>
#define N 5000
typedef struct {
char name[30]
int salary;
} person;
int main()
{
person* TAB = calloc(N, sizeof(struct));
FILE * input;
input = fopen("in.txt","r+");
int nr=0;
int r;
while(nr<5000)
{
fscanf(input,"%s",TAB[nr].name);
fscanf(input,"%d",TAB[nr].salary);
nr++;
}
printf("%s %d",TAB[1].name,TAB[1].salary);
fclose(input);
return 0;
}
答案 0 :(得分:1)
你真的应该避免在堆栈上放置那么多数据,这就像通常那样的普通变量。它将占用大约5000 *(30 + 4 * 5000)= 95 MB的堆栈空间,这可能比您的操作系统感觉更合理。
无论如何,修复不是在堆上分配它;修复是更改声明。我相信这是一个逻辑错误,因为你为每人分配了5000个工资空间,这可能不是你的意思。
此外,name
字段应该是一个字符数组,但您已将其声明为字符指针的数组,这就是警告的全部内容。
我相信你应该:
struct person
{
char name[30];
int salary;
};
这会将struct person TAB[N];
的内存使用量降低到大约5000 *(30 + 4)或大约166 KB,这更合理。这假设一个4字节int
,这是一种非常常见的情况。
最后,你的文件阅读代码设计得不是很好,它可能无法正常工作。
使用fgets()
来读取行,在失败时停止(即从不调用feof()
),然后将每行解析/标记为read。请记住,名称可以包含空格,这会使%s
中的sscanf()
停止。
答案 1 :(得分:1)
名称struct member不应该被声明为30个char指针,而且每个名称的工资是1,所以看起来应该是这样的
typedef struct {
char name[30]
int salary;
} person;
现在为了将它作为一个数组,你最好在堆上分配
person* persons = calloc(N, sizeof(struct));
现在您可以访问一个人的姓名和工资
persons[3].name
persons[3].salary
...
fgets(persons[nr].name,30,input); // although u may want to remove \n
答案 2 :(得分:0)
struct person
{
char* name[30];
我认为你的意思是char name[30]
。也就是说,如果您希望一个名称最多为29个字节。
稍后你会这样做:
fgets(&TAB[nr].name,30,input);
你为什么要拿地址?如果您进行上述更改,则TAB[nr].name
应为char[30]
类型,应根据需要退化为char*
。