如何return构造值?
How to return structure value?
我正在尝试 return 值并将它们打印到文件中...我声明了结构并读取文件获取值并将它们保存到指针中,但我做不到设法 return 他们发挥作用...
你能帮我吗?我只能 return 一个变量然后它给了我 (null) 而我不能 return 其他变量比如 .age
.efternamn
.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define MAX 10000
int elever = 1;
struct likaprogramms {
char civilekonom[50];
char högskoleingenjör[50];
char civilingenjör[50];
char systemutvecklare[50];
};
struct student {
char personnummer[32];
char förnamn[32];
char efternamn[32];
char gender[32];
char programmdife[32];
char age[32];
char email[32];
struct likaprogramms *likaprogramm;
};
struct student *personer;
struct programms {
char namnen;
char mcode;
char responsible;
char email;
};
void (*display[5])();
void* base(char *display[5]) {
//char fileA[MAX];
char tal;
int columns;
FILE *f;
f = fopen("elever.txt", "r");
personer = (struct student*) malloc(elever * sizeof(struct student));
personer->likaprogramm = malloc(sizeof(struct likaprogramms) * elever);
display = malloc(sizeof *display);
for (elever = 0; !feof(f);) {
tal = fgetc(f);
if (tal == '\n')
printf("\n");
{
elever++;
columns = 0;
if (tal == ' ') {
columns++;
}
if (columns == 0) {
fscanf(f, " %s", &personer[elever].personnummer);
//printf("%s",personer[elever].personnummer);
// return (personer[elever].personnummer);
//columns++;
}
columns++;
if (columns == 1) {
fscanf(f, " %s", &personer[elever].förnamn);
// return (personer[elever].förnamn);
}
columns++;
if (columns == 2) {
fscanf(f, " %s", &personer[elever].efternamn);
//return (personer[elever].efternamn);
}
columns++;
if (columns == 3) {
fscanf(f, " %s", &personer[elever].gender);
// return( personer[elever].gender);
}
columns++;
if (columns == 4) {
fscanf(f, " %s ", &personer[elever].programmdife);
// return( personer[elever].programmdife);
}
columns++;
if (columns == 5) {
fscanf(f, " %s", &personer[elever].age);
// return(personer[elever].age);
}
columns++;
if (columns == 6) {
fscanf(f, " %s", &personer[elever].email);
// return(personer[elever].email);
}
return &personer[elever];
}
//free(personer);
}
// return 0;
//fclose("elever.txt");
}
int i;
int main() {
display[i] = base(*display[i]);
FILE *h;
h = fopen("Filedatabase.txt", "w");
if (h == NULL) {
printf("Could not write the file!\n");
exit(1);
} else {
for (int i = 0; i < 7;) {
fprintf(h, "%s\n", display[i]);
printf("\n");
i++;
}
printf("open the file");
}
fclose(h);
free(display);
return 0;
}
你的代码中有一个很大的网格,我会尝试解码它,向你展示错误:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define MAX 10000
int elever = 1;
struct likaprogramms {
char civilekonom[50];
char högskoleingenjör[50];
char civilingenjör[50];
char systemutvecklare[50];
};
struct student {
char personnummer[32];
char förnamn[32];
char efternamn[32];
char gender[32];
char programmdife[32];
char age[32];
char email[32];
struct likaprogramms *likaprogramm;
};
struct student *personer;
struct programms {
char namnen;
char mcode;
char responsible;
char email;
};
void (*display[5])();
display
是一个包含 5 个指向 void
函数的数组,这些函数采用未确定数量的参数(不完整的类型定义,因为要存储的函数的参数类型和数量是not specified in the definition) 这在 C 中维护以实现遗留代码兼容性,但今天不推荐使用。虽然这不是错误,但我不明白你为什么要为数组设计如此复杂的声明。
void* base(char *display[5]) {
这里,display
是一个包含 5 个指向 char 的指针的数组(或者字符串,如果它们要被 '[=21=]'
终止)问题是你已经命名了 display
局部变量与全局数组同名(也有 5 个指向函数的指针)所以我现在唯一能说的是你以后 运行 会遇到麻烦。
//char fileA[MAX];
char tal;
int columns;
FILE *f;
f = fopen("elever.txt", "r");
personer = (struct student*) malloc(elever * sizeof(struct student));
personer->likaprogramm = malloc(sizeof(struct likaprogramms) * elever);
display = malloc(sizeof *display);
for (elever = 0; !feof(f);) {
feof(f)
return 仅在 之后 您尝试读取文件后才有效,而不是在检查之前。虽然这不是问题,但您将使用此 for
循环将垃圾记录添加到您的数组中,因为只有当您已经尝试读取不完整的内容时,它才会 return 您 EOF(但您已将其添加到数据库中)。
tal = fgetc(f);
您之前可以使用 while ((tal = fgetc(f)) != EOF)
代替(因为您正在一个接一个地阅读字符)。但是为了这个目的,tal
必须声明为 int
(而不是 char
),因为 EOF
是一个整数常量,不在任何可能的字符值之外,你可以存储在 char
变量。无论如何,您都可以在后续代码中对 int
变量进行操作,但这样一来,它允许您在处理任何无效数据之前检测文件结束条件。
if (tal == '\n')
printf("\n");
{
elever++;
columns = 0;
if (tal == ' ') {
columns++;
}
if (columns == 0) {
fscanf(f, " %s", &personer[elever].personnummer);
//printf("%s",personer[elever].personnummer);
// return (personer[elever].personnummer);
//columns++;
}
columns++;
if (columns == 1) {
fscanf(f, " %s", &personer[elever].förnamn);
// return (personer[elever].förnamn);
}
columns++;
if (columns == 2) {
fscanf(f, " %s", &personer[elever].efternamn);
//return (personer[elever].efternamn);
}
columns++;
if (columns == 3) {
fscanf(f, " %s", &personer[elever].gender);
// return( personer[elever].gender);
}
columns++;
if (columns == 4) {
fscanf(f, " %s ", &personer[elever].programmdife);
// return( personer[elever].programmdife);
}
columns++;
if (columns == 5) {
fscanf(f, " %s", &personer[elever].age);
// return(personer[elever].age);
}
columns++;
if (columns == 6) {
fscanf(f, " %s", &personer[elever].email);
// return(personer[elever].email);
}
return &personer[elever];
}
//free(personer);
}
// return 0;
//fclose("elever.txt");
}
int i;
int main() {
display[i] = base(*display[i]);
为什么你混淆了 reader 分配给 display[i]
与未初始化的 i
变量(作为全局变量,它是零)而不是说 display[0] = base(*display[0]);
更重要的是,为什么你要为 base()
的结果赋一个函数指针单元格,它应该是一个结构。对一个函数指针你唯一能做的就是给它赋值并执行它指向的函数。但是您正在分配一个指向结构的指针(该信息隐藏在您将其定义为 returning void *
的事实之下,我不知道您从哪里学到的,但不值得在这里使用)如果你的功能是为数组动态分配内存,数组应该被定义为struct student * display[5];
或更好的struct student **display;
(因为动态内存分配的性质,您可以处理数组中可变数量的结构。
FILE *h;
h = fopen("Filedatabase.txt", "w");
if (h == NULL) {
printf("Could not write the file!\n");
exit(1);
} else {
for (int i = 0; i < 7;) {
如果您已经为包含五个条目的数组编写了所有内容,为什么还要在这里增加七个?在代码中使用常量很重要,因此您永远不会因为这个错误而失败。
fprintf(h, "%s\n", display[i]);
printf("\n");
i++;
}
printf("open the file");
}
fclose(h);
free(display);
return 0;
}
如果你想学习 return 一个完整的结构,这里有一个示例代码可以完成我猜你想做的事情,return 构建一个结构并将其复制回在作业中的适当位置(但在这种情况下没有使用 malloc
,因此,程序中没有动态内容,您将始终为 5 个学生设置 space --- 或常量---和一个适当的 struct student
数组已经为你分配了)这是一个比你的更简单的例子,基于你的代码来说明 C 函数中的结构 return (我认为它会更容易理解并更好地在您的代码中使用):
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* the two macros below allow pretty printing of error,
* including the file and the line where the error
* was detected. */
#define F(_fmt) "%s:%d:"_fmt,__FILE__,__LINE__
#define ERR(_cod, _fmt, ...) do{ \
fprintf(stderr, F(_fmt),##__VA_ARGS__); \
if(_cod) \
exit(_cod); \
}while(0)
struct student {
char personnummer[32];
char förnamn[32];
char efternamn[32];
char gender[32];
char programmdife[32];
char age[32];
char email[32];
struct likaprogramms *likaprogramm; /* I don;t use this field in my code */
};
/* use a constant, so if you want to change it later,
* you need only to change it here. */
#define N_STUDENTS (5)
#define MAX_LINE 1000
/* static allocation done by the compiler */
struct student display[N_STUDENTS];
/* the function now reads a single student from the already
* open FILE descriptor f, and returns a struct student,
* filled with the read data, ready for assignment in the
* proper place. */
struct student base(FILE *f)
{
//char fileA[MAX];
int tal;
int columns;
/* use a local structure that will be copied back to
* the proper place in the return statement */
struct student return_value = {0};
char line[MAX_LINE];
char *p = fgets(line, sizeof line, f);
if (!p) { /* EOF */
return return_value; /* return it as it is to
* indicate nothing was
* returned */
}
/* process the fields */
p = strtok(p, " \t\n");
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.personnummer, p,
sizeof return_value.personnummer);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.förnamn, p,
sizeof return_value.förnamn);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.efternamn, p,
sizeof return_value.efternamn);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.gender, p,
sizeof return_value.gender);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.programmdife, p,
sizeof return_value.programmdife);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.age, p,
sizeof return_value.age);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.email, p,
sizeof return_value.email);
/* the full reading process for each field could have
* been condensed in a macro call for each field, as it
* is done in the macro definition below to print entries.
* I preferred to shorten one and not the other to show
* the better readability of the macro code. */
return return_value;
}
void print_entry(struct student *entry, FILE *out)
{
/* print the result for field _fn of entry variable */
#define PR(_fn) fprintf(out, #_fn ": %s\n", entry->_fn)
PR(personnummer);
PR(förnamn);
PR(efternamn);
PR(gender);
PR(programmdife);
PR(age);
PR(email);
#undef PR /* not needed anymore */
}
int main()
{
int i;
char *students_filename = "elever.txt";
FILE *in = fopen(students_filename, "r");
if (!in) {
ERR(1, "Cannot open %s: %s (errno = %d)\n",
students_filename, strerror(errno), errno);
/* NOTREACHED */
}
for (i = 0; i < N_STUDENTS; i++) {
display[i] = base(in); /* assign to display[i] the read
* data from next student in in
* FILE descriptor */
}
fclose(in); /* close file */
char *database_filename = "Filedatabase.txt";
FILE *out = fopen(database_filename, "w");
if (!out) {
ERR(1, "Cannot create %s: %s (errno = %d)\n",
database_filename, strerror(errno), errno);
/* NOTREACHED */
}
for (i = 0; i < N_STUDENTS; i++) {
print_entry(&display[i], out); /* we pass it by
* reference to
* minimice copying
*/
}
fclose(out); /* again, flush buffer and close file */
return 0;
}
我正在尝试 return 值并将它们打印到文件中...我声明了结构并读取文件获取值并将它们保存到指针中,但我做不到设法 return 他们发挥作用...
你能帮我吗?我只能 return 一个变量然后它给了我 (null) 而我不能 return 其他变量比如 .age
.efternamn
.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define MAX 10000
int elever = 1;
struct likaprogramms {
char civilekonom[50];
char högskoleingenjör[50];
char civilingenjör[50];
char systemutvecklare[50];
};
struct student {
char personnummer[32];
char förnamn[32];
char efternamn[32];
char gender[32];
char programmdife[32];
char age[32];
char email[32];
struct likaprogramms *likaprogramm;
};
struct student *personer;
struct programms {
char namnen;
char mcode;
char responsible;
char email;
};
void (*display[5])();
void* base(char *display[5]) {
//char fileA[MAX];
char tal;
int columns;
FILE *f;
f = fopen("elever.txt", "r");
personer = (struct student*) malloc(elever * sizeof(struct student));
personer->likaprogramm = malloc(sizeof(struct likaprogramms) * elever);
display = malloc(sizeof *display);
for (elever = 0; !feof(f);) {
tal = fgetc(f);
if (tal == '\n')
printf("\n");
{
elever++;
columns = 0;
if (tal == ' ') {
columns++;
}
if (columns == 0) {
fscanf(f, " %s", &personer[elever].personnummer);
//printf("%s",personer[elever].personnummer);
// return (personer[elever].personnummer);
//columns++;
}
columns++;
if (columns == 1) {
fscanf(f, " %s", &personer[elever].förnamn);
// return (personer[elever].förnamn);
}
columns++;
if (columns == 2) {
fscanf(f, " %s", &personer[elever].efternamn);
//return (personer[elever].efternamn);
}
columns++;
if (columns == 3) {
fscanf(f, " %s", &personer[elever].gender);
// return( personer[elever].gender);
}
columns++;
if (columns == 4) {
fscanf(f, " %s ", &personer[elever].programmdife);
// return( personer[elever].programmdife);
}
columns++;
if (columns == 5) {
fscanf(f, " %s", &personer[elever].age);
// return(personer[elever].age);
}
columns++;
if (columns == 6) {
fscanf(f, " %s", &personer[elever].email);
// return(personer[elever].email);
}
return &personer[elever];
}
//free(personer);
}
// return 0;
//fclose("elever.txt");
}
int i;
int main() {
display[i] = base(*display[i]);
FILE *h;
h = fopen("Filedatabase.txt", "w");
if (h == NULL) {
printf("Could not write the file!\n");
exit(1);
} else {
for (int i = 0; i < 7;) {
fprintf(h, "%s\n", display[i]);
printf("\n");
i++;
}
printf("open the file");
}
fclose(h);
free(display);
return 0;
}
你的代码中有一个很大的网格,我会尝试解码它,向你展示错误:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#define MAX 10000
int elever = 1;
struct likaprogramms {
char civilekonom[50];
char högskoleingenjör[50];
char civilingenjör[50];
char systemutvecklare[50];
};
struct student {
char personnummer[32];
char förnamn[32];
char efternamn[32];
char gender[32];
char programmdife[32];
char age[32];
char email[32];
struct likaprogramms *likaprogramm;
};
struct student *personer;
struct programms {
char namnen;
char mcode;
char responsible;
char email;
};
void (*display[5])();
display
是一个包含 5 个指向 void
函数的数组,这些函数采用未确定数量的参数(不完整的类型定义,因为要存储的函数的参数类型和数量是not specified in the definition) 这在 C 中维护以实现遗留代码兼容性,但今天不推荐使用。虽然这不是错误,但我不明白你为什么要为数组设计如此复杂的声明。
void* base(char *display[5]) {
这里,display
是一个包含 5 个指向 char 的指针的数组(或者字符串,如果它们要被 '[=21=]'
终止)问题是你已经命名了 display
局部变量与全局数组同名(也有 5 个指向函数的指针)所以我现在唯一能说的是你以后 运行 会遇到麻烦。
//char fileA[MAX];
char tal;
int columns;
FILE *f;
f = fopen("elever.txt", "r");
personer = (struct student*) malloc(elever * sizeof(struct student));
personer->likaprogramm = malloc(sizeof(struct likaprogramms) * elever);
display = malloc(sizeof *display);
for (elever = 0; !feof(f);) {
feof(f)
return 仅在 之后 您尝试读取文件后才有效,而不是在检查之前。虽然这不是问题,但您将使用此 for
循环将垃圾记录添加到您的数组中,因为只有当您已经尝试读取不完整的内容时,它才会 return 您 EOF(但您已将其添加到数据库中)。
tal = fgetc(f);
您之前可以使用 while ((tal = fgetc(f)) != EOF)
代替(因为您正在一个接一个地阅读字符)。但是为了这个目的,tal
必须声明为 int
(而不是 char
),因为 EOF
是一个整数常量,不在任何可能的字符值之外,你可以存储在 char
变量。无论如何,您都可以在后续代码中对 int
变量进行操作,但这样一来,它允许您在处理任何无效数据之前检测文件结束条件。
if (tal == '\n')
printf("\n");
{
elever++;
columns = 0;
if (tal == ' ') {
columns++;
}
if (columns == 0) {
fscanf(f, " %s", &personer[elever].personnummer);
//printf("%s",personer[elever].personnummer);
// return (personer[elever].personnummer);
//columns++;
}
columns++;
if (columns == 1) {
fscanf(f, " %s", &personer[elever].förnamn);
// return (personer[elever].förnamn);
}
columns++;
if (columns == 2) {
fscanf(f, " %s", &personer[elever].efternamn);
//return (personer[elever].efternamn);
}
columns++;
if (columns == 3) {
fscanf(f, " %s", &personer[elever].gender);
// return( personer[elever].gender);
}
columns++;
if (columns == 4) {
fscanf(f, " %s ", &personer[elever].programmdife);
// return( personer[elever].programmdife);
}
columns++;
if (columns == 5) {
fscanf(f, " %s", &personer[elever].age);
// return(personer[elever].age);
}
columns++;
if (columns == 6) {
fscanf(f, " %s", &personer[elever].email);
// return(personer[elever].email);
}
return &personer[elever];
}
//free(personer);
}
// return 0;
//fclose("elever.txt");
}
int i;
int main() {
display[i] = base(*display[i]);
为什么你混淆了 reader 分配给 display[i]
与未初始化的 i
变量(作为全局变量,它是零)而不是说 display[0] = base(*display[0]);
更重要的是,为什么你要为 base()
的结果赋一个函数指针单元格,它应该是一个结构。对一个函数指针你唯一能做的就是给它赋值并执行它指向的函数。但是您正在分配一个指向结构的指针(该信息隐藏在您将其定义为 returning void *
的事实之下,我不知道您从哪里学到的,但不值得在这里使用)如果你的功能是为数组动态分配内存,数组应该被定义为struct student * display[5];
或更好的struct student **display;
(因为动态内存分配的性质,您可以处理数组中可变数量的结构。
FILE *h;
h = fopen("Filedatabase.txt", "w");
if (h == NULL) {
printf("Could not write the file!\n");
exit(1);
} else {
for (int i = 0; i < 7;) {
如果您已经为包含五个条目的数组编写了所有内容,为什么还要在这里增加七个?在代码中使用常量很重要,因此您永远不会因为这个错误而失败。
fprintf(h, "%s\n", display[i]);
printf("\n");
i++;
}
printf("open the file");
}
fclose(h);
free(display);
return 0;
}
如果你想学习 return 一个完整的结构,这里有一个示例代码可以完成我猜你想做的事情,return 构建一个结构并将其复制回在作业中的适当位置(但在这种情况下没有使用 malloc
,因此,程序中没有动态内容,您将始终为 5 个学生设置 space --- 或常量---和一个适当的 struct student
数组已经为你分配了)这是一个比你的更简单的例子,基于你的代码来说明 C 函数中的结构 return (我认为它会更容易理解并更好地在您的代码中使用):
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* the two macros below allow pretty printing of error,
* including the file and the line where the error
* was detected. */
#define F(_fmt) "%s:%d:"_fmt,__FILE__,__LINE__
#define ERR(_cod, _fmt, ...) do{ \
fprintf(stderr, F(_fmt),##__VA_ARGS__); \
if(_cod) \
exit(_cod); \
}while(0)
struct student {
char personnummer[32];
char förnamn[32];
char efternamn[32];
char gender[32];
char programmdife[32];
char age[32];
char email[32];
struct likaprogramms *likaprogramm; /* I don;t use this field in my code */
};
/* use a constant, so if you want to change it later,
* you need only to change it here. */
#define N_STUDENTS (5)
#define MAX_LINE 1000
/* static allocation done by the compiler */
struct student display[N_STUDENTS];
/* the function now reads a single student from the already
* open FILE descriptor f, and returns a struct student,
* filled with the read data, ready for assignment in the
* proper place. */
struct student base(FILE *f)
{
//char fileA[MAX];
int tal;
int columns;
/* use a local structure that will be copied back to
* the proper place in the return statement */
struct student return_value = {0};
char line[MAX_LINE];
char *p = fgets(line, sizeof line, f);
if (!p) { /* EOF */
return return_value; /* return it as it is to
* indicate nothing was
* returned */
}
/* process the fields */
p = strtok(p, " \t\n");
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.personnummer, p,
sizeof return_value.personnummer);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.förnamn, p,
sizeof return_value.förnamn);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.efternamn, p,
sizeof return_value.efternamn);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.gender, p,
sizeof return_value.gender);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.programmdife, p,
sizeof return_value.programmdife);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.age, p,
sizeof return_value.age);
p = strtok(NULL, " \t\n"); /* next field */
if (!p) { /* no more fields */
return return_value; /* same as above */
}
strncpy(return_value.email, p,
sizeof return_value.email);
/* the full reading process for each field could have
* been condensed in a macro call for each field, as it
* is done in the macro definition below to print entries.
* I preferred to shorten one and not the other to show
* the better readability of the macro code. */
return return_value;
}
void print_entry(struct student *entry, FILE *out)
{
/* print the result for field _fn of entry variable */
#define PR(_fn) fprintf(out, #_fn ": %s\n", entry->_fn)
PR(personnummer);
PR(förnamn);
PR(efternamn);
PR(gender);
PR(programmdife);
PR(age);
PR(email);
#undef PR /* not needed anymore */
}
int main()
{
int i;
char *students_filename = "elever.txt";
FILE *in = fopen(students_filename, "r");
if (!in) {
ERR(1, "Cannot open %s: %s (errno = %d)\n",
students_filename, strerror(errno), errno);
/* NOTREACHED */
}
for (i = 0; i < N_STUDENTS; i++) {
display[i] = base(in); /* assign to display[i] the read
* data from next student in in
* FILE descriptor */
}
fclose(in); /* close file */
char *database_filename = "Filedatabase.txt";
FILE *out = fopen(database_filename, "w");
if (!out) {
ERR(1, "Cannot create %s: %s (errno = %d)\n",
database_filename, strerror(errno), errno);
/* NOTREACHED */
}
for (i = 0; i < N_STUDENTS; i++) {
print_entry(&display[i], out); /* we pass it by
* reference to
* minimice copying
*/
}
fclose(out); /* again, flush buffer and close file */
return 0;
}