在函数中循环以在c中的结构中存储数据
我正在尝试编写一个函数,允许我在一个结构中输入三个人的姓名、年龄和薪水。然后我想把它们打印出来。我刚上了几周的第一节编程课,请耐心听我说,我找不到任何对我有意义的例子。我在没有[I]的情况下运行了这个循环,但数据只会写在自己的上面。(我想?)我不想让代码为我编写,但如果有人知道我正在尝试做什么,或者可以为我指出正确的方向,我将非常感激。(很多printf现在就在那里,稍后将被删除。)在函数中循环以在c中的结构中存储数据,c,C,我正在尝试编写一个函数,允许我在一个结构中输入三个人的姓名、年龄和薪水。然后我想把它们打印出来。我刚上了几周的第一节编程课,请耐心听我说,我找不到任何对我有意义的例子。我在没有[I]的情况下运行了这个循环,但数据只会写在自己的上面。(我想?)我不想让代码为我编写,但如果有人知道我正在尝试做什么,或者可以为我指出正确的方向,我将非常感激。(很多printf现在就在那里,稍后将被删除。) #包括 #包括 #包括 #定义尺寸20 结构管理器{ 字符*名称[大小]; 国际*年龄[4]; 国际*薪金[10
#包括
#包括
#包括
#定义尺寸20
结构管理器{
字符*名称[大小];
国际*年龄[4];
国际*薪金[10];
}员工;
void addInfo(结构管理器*文件[]);
内部主(空){
printf(“\n\n”);
printf(“\t************************\n\t*输入1以添加员工。*\n\t*输入2以搜索。\t*\n\t*输入3以更新。\t*\n\t*输入4以删除。\t*\n\t*输入0以退出。\t*\n\t*********************\n\n”);
addInfo(和员工);
返回0;
}
void addInfo(结构管理器*文件[]){
int i=0;
int计数器=1;
int-otherCounter=1;
对于(i=0;i<3;i++){
/*printf(“输入员工的姓名#%d:\n”),otherCounter;
获取(&employee.name[i]);
printf(“输入员工的年龄#%d:\n”,其他计数器);
获取(&employee.age[i]);
printf(“输入员工的工资#%d:\n”,其他计数器);
获取(&employee.salary[i]);
*/
printf(“输入员工的姓名#%d:\n”),otherCounter;
scanf(“%s”和employee.name[i]);
printf(“员工姓名:%s\n”,Employee.name[i]);
printf(“输入员工的年龄#%d:\n”,其他计数器);
scanf(“%d”和employee.age[i]);
printf(“员工年龄:%d\n”,Employee.age[i]);
printf(“输入员工的工资#%d:\n”,其他计数器);
scanf(“%d”和员工工资[i]);
printf(“员工工资:%d\n”,员工工资[i]);
++其他计数器;
}
对于(i=0;i<3;i++){
printf(“\n员工%d:\n”,计数器);
printf(“员工姓名:%s\n”,Employee.name[i]);
printf(“员工年龄:%d\n”,Employee.age[i]);
printf(“员工工资:%d\n\n”,Employee.salary[i]);
++计数器;
}
}
看起来你完全糊涂了。你所有的定义看起来都很奇怪,你使用这些值的方式是错误的
从以下内容开始:
#define MAX_NAME 20
#define MAX_EMPLOYEES 100
struct Employee
{
char name[MAX_NAME];
int age;
int salary;
};
struct Employee employees[MAX_EMPLOYEES];
让你的职能部门只阅读一名员工。如果您确实希望提示说明您正在读取的员工编号,可以将其作为参数传入
void readEmployeeInfo(struct Employee *e)
{
printf("Enter name:\n");
scanf("%s", e->name);
printf("Enter age:\n");
scanf("%d", e->age);
printf("Enter salary:\n");
scanf("%d", e->salary);
}
添加其他功能,如显示员工记录。这将保持它的整洁,并确保函数只做一件事
要读取循环中的员工数,请执行以下操作:
for (int i = 0; i < 3; i++)
{
readEmployeeInfo(&employees[i]);
}
for(int i=0;i<3;i++)
{
readEmployeeInfo(&employees[i]);
}
这应该让你开始了。看起来你完全糊涂了。你所有的定义看起来都很奇怪,你使用这些值的方式是错误的 从以下内容开始:
#define MAX_NAME 20
#define MAX_EMPLOYEES 100
struct Employee
{
char name[MAX_NAME];
int age;
int salary;
};
struct Employee employees[MAX_EMPLOYEES];
让你的职能部门只阅读一名员工。如果您确实希望提示说明您正在读取的员工编号,可以将其作为参数传入
void readEmployeeInfo(struct Employee *e)
{
printf("Enter name:\n");
scanf("%s", e->name);
printf("Enter age:\n");
scanf("%d", e->age);
printf("Enter salary:\n");
scanf("%d", e->salary);
}
添加其他功能,如显示员工记录。这将保持它的整洁,并确保函数只做一件事
要读取循环中的员工数,请执行以下操作:
for (int i = 0; i < 3; i++)
{
readEmployeeInfo(&employees[i]);
}
for(int i=0;i<3;i++)
{
readEmployeeInfo(&employees[i]);
}
这应该可以让你开始了。比你原来的方法多走一步,不要使用
scanf()
接受用户输入,也不要在没有检查返回值的情况下使用scanf()
。为什么?scanf()
对于新的C程序员来说充满了陷阱,因为在stdin
中,字符将保持未读状态,只要出现匹配失败,字符就会再次咬到你。此外,使用scanf()
读取字符串而不提供字段宽度修改器与使用gets()
一样不安全,需要进行解释。看
相反,使用一个面向行的输入函数,如fgets()
,具有足够大小的缓冲区,以读取所有用户输入(不要忽略缓冲区大小,如果在微控制器上编程,请进行调整,否则1K缓冲区就可以了),这样可以确保用户输入的所有字符(在除猫踩键盘的极端情况外的所有情况下)都会被读取,并且stdin
中不会有任何内容会影响您下一次尝试的输入。您还可以使用POSIXgetline()
,这是第二个常用的面向行的输入函数
使用面向行的输入函数的唯一警告是,它们读取并将尾部的'\n'
包含在它们填充的缓冲区中。这不是问题,只需使用strcspn()
获取'\n'
字符前面的字符数,然后用nul终止字符'\0'
覆盖尾随的'\n'
,相当于普通的旧0
。例如,如果您读入缓冲区,请说char buf[1024]
,并且您需要修剪试验换行符,只需使用:
buf[strcspn (buf, "\n")] = 0;
(如果在windows上以先出现的日期开始修剪,则也可以包含'\r'
回车符,例如如果使用“\r\n”
作为分隔符,DOS行神秘地进入输入)
不要将#包含在标题中。这是DOS时代的错误,并且100%不可移植到windows以外的任何设备
将其用于一次读取一名员工的信息
在你的情况下,在@paddy的回答下面的评论之后,你不想写你的“添加”函数来“添加”特定数量的任何东西,你想写你的添加函数
fputs ("\nemployee name : ", stdout); /* no conversion - use fputs */
if (fgets (buf, MAXC, stdin) == NULL) { /* read all input with fgets() */
fputs ("(user canceled input)\n", stderr); /* validate EVERY input */
return -1;
}
len = strcspn (buf, "\r\n"); /* length before either "\r\n" */
if (len >= MAXNM) { /* validate length */
fputs ("error: name too long.\n", stderr);
return 0;
}
buf[len] = 0; /* trim trailing '\n' */
memcpy (e->name, buf, len + 1); /* copy to name */
fputs ("employee age : ", stdout); /* prompt for age */
if (!fgets (buf, MAXC, stdin)) { /* validate EVERY input */
fputs ("(user canceled input)\n", stderr);
return -1;
}
if (sscanf (buf, "%u", &e->age) != 1) { /* validate conversion */
fputs ("error: invalid unsigned input\n", stderr);
return 0;
}
void prnemployees (employee *e, int n)
{
for (int i = 0; i < n; i++)
printf ("\n%s\n age : %u\n salary : %u\n",
e[i].name, e[i].age, e[i].salary);
}
int main (void) {
int n = 0; /* input counter */
employee emp[NEMP] = {{ .name = "" }}; /* array of employee, initialize all zero */
while (n < NEMP) {
int result = addemployee (&emp[n]); /* add employee VALIDATE return */
if (result == -1) /* if user canceled, stop input */
break;
else if (result == 1) /* if good input, increment count */
n++;
/* for 0 return, do nothing, error message output in funciton */
}
prnemployees (emp, n);
}
#include <stdio.h>
#include <string.h>
#define NEMP 3 /* if you need a constant, #define one (or more) */
#define MAXNM 20
#define MAXC 1024
typedef struct { /* typedef makes working with structs convenient */
char name[MAXNM];
unsigned age, salary;
} employee;
int addemployee (employee *e)
{
char buf[MAXC];
size_t len;
fputs ("\nemployee name : ", stdout); /* no conversion - use fputs */
if (fgets (buf, MAXC, stdin) == NULL) { /* read all input with fgets() */
fputs ("(user canceled input)\n", stderr); /* validate EVERY input */
return -1;
}
len = strcspn (buf, "\r\n"); /* length before either "\r\n" */
if (len >= MAXNM) { /* validate length */
fputs ("error: name too long.\n", stderr);
return 0;
}
buf[len] = 0; /* trim trailing '\n' */
memcpy (e->name, buf, len + 1); /* copy to name */
fputs ("employee age : ", stdout); /* prompt for age */
if (!fgets (buf, MAXC, stdin)) { /* validate EVERY input */
fputs ("(user canceled input)\n", stderr);
return -1;
}
if (sscanf (buf, "%u", &e->age) != 1) { /* validate conversion */
fputs ("error: invalid unsigned input\n", stderr);
return 0;
}
fputs ("employee salary : ", stdout); /* prompt for salary */
if (!fgets (buf, MAXC, stdin)) { /* validate EVERY input */
fputs ("(user canceled input)\n", stderr);
return -1;
}
if (sscanf (buf, "%u", &e->salary) != 1) { /* validate conversion */
fputs ("error: invalid unsigned input\n", stderr);
return 0;
}
return 1;
}
void prnemployees (employee *e, int n)
{
for (int i = 0; i < n; i++)
printf ("\n%s\n age : %u\n salary : %u\n",
e[i].name, e[i].age, e[i].salary);
}
int main (void) {
int n = 0; /* input counter */
employee emp[NEMP] = {{ .name = "" }}; /* array of employee, initialize all zero */
while (n < NEMP) {
int result = addemployee (&emp[n]); /* add employee VALIDATE return */
if (result == -1) /* if user canceled, stop input */
break;
else if (result == 1) /* if good input, increment count */
n++;
/* for 0 return, do nothing, error message output in funciton */
}
prnemployees (emp, n);
}
$ ./bin/addemployee
employee name : Mickey Mouse
employee age : 92
employee salary : 200000
employee name : Minnie Mouse
employee age : too old
error: invalid unsigned input
employee name : Minnie Mouse
employee age : 92
employee salary : 250000
employee name : Pluto (dog)
employee age : 90
employee salary : bone
error: invalid unsigned input
employee name : Pluto (dog)
employee age : 90
employee salary : 10000
Mickey Mouse
age : 92
salary : 200000
Minnie Mouse
age : 92
salary : 250000
Pluto (dog)
age : 90
salary : 10000