简体   繁体   English

将结构存储在数组中时遇到问题

[英]Trouble storing a struct in an array

I want to create a database sort of, that stores a list of 5000 names and 5000 coresponding salaries into an array, I simply can't find the problem since the console either crashes or the compiler gives me the following error: "cannot convert 'char* ( )[30]' to 'char ' for argument '1' to 'char*' fgets(char*,int,*FILE)".我想创建一个数据库,将 5000 个姓名和 5000 个相应薪水的列表存储到一个数组中,我根本找不到问题,因为控制台崩溃或编译器给我以下错误:“无法转换” char* ( )[30]' to 'char ' for argument '1' to 'char*' fgets(char*,int,*FILE)”。

EDIT: I changed whatever I could figure out in the code, and I seem to have an issue with this line in particular:编辑:我改变了我在代码中发现的任何东西,而且我似乎特别对这一行有疑问:

person* TAB = calloc(N, sizeof(struct)); 

I can't spot other errors(lack of experience), and I don't know exactly what to use instead of fgets to put in a line.我无法发现其他错误(缺乏经验),而且我不知道该用什么来代替 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;
}

You really should avoid putting that much data on the stack, which is what a normal variable like that will generally do.你真的应该避免把那么多数据放在堆栈上,这是一个像这样的普通变量通常会做的事情。 It will occupy around 5000 * (30 + 4 * 5000) = 95 MB of stack space, which might be more than your operating system feels is reasonable.它将占用大约 5000 * (30 + 4 * 5000) = 95 MB 的堆栈空间,这可能超出操作系统认为合理的范围。

Anyway, the fix is not to allocate this on the heap;无论如何,解决办法不是在堆上分配它; the fix is to change the declaration.解决方法是更改声明。 I believe there's a logic error, since you allocate space for 5000 salaries per person , which is probably not what you meant.我认为存在逻辑错误,因为您为每人5000 薪水分配了空间,这可能不是您的意思。

Also, the name field should be an array of characters, but you've declared it as an array of character pointers , which is what the warnings are all about.此外, name字段应该是一个字符数组,但您已将其声明为一个字符指针数组,这就是警告的全部内容。

I believe you should have:我相信你应该有:

struct person
{
    char name[30];
    int  salary;
};

This will drop the memory usage for struct person TAB[N];这将减少 memory 对struct person TAB[N]; down to around 5000 * (30 + 4) or around 166 KB which is way more reasonable.减少到大约 5000 * (30 + 4) 或大约 166 KB,这是更合理的方式。 This assumes a 4-byte int which is a pretty common situation.这假定一个 4 字节的int ,这是一种很常见的情况。

Finally, your file reading code is not very nicely designed, it will probably not work.最后,您的文件读取代码设计得不是很好,它可能无法运行。

Look into using fgets() to read lines, stopping when it fails (ie never calling feof() ), and then parsing/tokenizing each line as read.考虑使用fgets()读取行,在失败时停止(即从不调用feof() ),然后将每一行解析/标记为读取。 Remember that names can contain whitespace, which will make %s in sscanf() stop.请记住,名称可以包含空格,这将使sscanf()%s停止。

The name struct member should not be declared as 30 char pointers and the salary is one per name so it should look something like this名称结构成员不应声明为 30 个字符指针,薪水是每个名称一个,因此它应该看起来像这样

typedef struct {
  char name[30]
  int  salary;
} person;

Now in order to have it as an array you are best off allocating on the heap现在为了把它作为一个数组,你最好在堆上分配

person* persons = calloc(N, sizeof(struct));

Now you can access the name and salary of one person现在您可以访问一个人的姓名和薪水

persons[3].name
persons[3].salary

...

fgets(persons[nr].name,30,input); // although you may want to remove \n
struct person
{
    char* name[30];

I think you mean char name[30] .我认为你的意思是char name[30] That is if you want one name of at most 29 bytes.也就是说,如果您想要一个最多 29 个字节的名称。

Later on you do:稍后你会这样做:

fgets(&TAB[nr].name,30,input);

Why are you taking the address?你为什么要拿地址? If you make the change above, the TAB[nr].name should be of type char[30] , which should degenerate into a char* as desired.如果您进行上述更改,则TAB[nr].name应该是char[30]类型,它应该根据需要退化为char*

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

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