[英]Problems with arrays within structures and files in C
我正在尝试使用C语言中的结构来存储课程名称的信息以及我上课的日期。存储名称不是问题。 当我尝试在数组中存储多天(工作日作为整数,即星期一= 1)时,会出现问题。
这就是我所拥有的:
#include<stdio.h>
#include<string.h>
struct lessons{
char name[20];
int day[3];
};
changelessons(){
int i, k;
struct lessons give[1], receive[1];
FILE *fptr;
fptr = fopen("lessons","wb");
fflush(stdin);
printf("\n\t ~ Change lessons ~");
printf("\n\nWhat's the lesson called?: ");
gets(give[0].name);
printf("\nHow many days do you have it?\n");
scanf("%d", &k);
for(i = 0; i < k; i++); { // Asks the weekday number for each day you have the lesson
printf("What day is lesson %d?: ", i);
scanf("%d", &give[0].day[i]);
}
fwrite(give, sizeof(give), 1, fptr);
fclose(fptr);
fptr = fopen("lessons", "rb");
fread(receive, sizeof(receive), 1, fptr);
printf("\n\t ~ Updated information: ~\n\nLesson name: %s\nDay: %d", receive[0].name, receive[0].day[1]);
for(i = 1; i < k; i++); { // Prints the extra weekdays if there are any
printf(", day: %d", receive[0].day[i]);
}
printf("\n\n");
fclose(fptr);
}
showlessons(){
struct lessons give[1], receive[1];
FILE *fptr;
fptr = fopen("lessons", "rb");
fread(receive, sizeof(receive), 1, fptr);
printf("\t ~ Current information: ~ \n\nLesson name: %s\nDay: %d\n\n", receive[0].name, receive[0].day[0]);
}
int main(){
showlessons();
changelessons();
return 0;
}
此外,在第一个for循环中,它只会循环一次,而不管k等于什么。
在此先感谢您的帮助!
for(i = 0; i < k; i++);
应该
for(i = 0; i < k; i++)
额外的半结肠是一个问题。 您的循环代码不是循环的一部分。 半冒号终止循环。
nicomp指出了最明显的错误。
但我还想指出我的代码中的一些问题:
fflush(stdin);
这是错误的,未定义的行为。 fflush
用于刷新输出流, stdin
是输入流。 请参阅使用fflush(stdin)
。
我知道在Windows中fflush(stdin)
清除输入缓冲区,但我强烈建议不要使用它,因为在中继仅在一个操作系统中可用的功能时会丢失可移植性。 如果您不关心可移植性,请使用它。 如果你使用它,因为scanf
在输入缓冲区中留下了东西,请改用:
int c; while((c = getchar()) != '\\n' && c != EOF);
这是便携式的。
永远不会在2018年使用gets
。 gets
是一个不安全,危险的函数,已在C99中弃用,并且有充分的理由:它不考虑缓冲区的大小,如果输入的文本比缓冲区可以存储的长,它会溢出缓冲区。 这是一个等待发生的事故。 所以,永远不要gets
试。 请改用fgets
,如果您不想使用换行符,可以将其删除:
fgets(give[0].name, sizeof give[0].name, stdin); give[0].name[sizeof(give[0].name) - 1] = 0; // remove possible newline
为什么要声明一个尺寸为1的struct lessons
数组? 重点是什么? 你不需要一个数组。 你可以像这样写:
struct lessons give, receive; ... printf("\\n\\nWhat's the lesson called?: "); fgets(give.name, sizeof give.name, stdin); give.name[strcspn(give.name, "\\n")] = 0; ... fwrite(&give, sizeof give, 1, fptr); fclose(fptr); ... fptr = fopen("lessons", "rb"); fread(&receive, sizeof receive, 1, fptr);
另外不要忘记检查fwrite
和fread
的返回值。
检查fopen
的返回值,如果返回NULL
,则不能使用fread
或fwrite
。 打印错误值并返回/退出。
stdout
是缓冲的,当你用printf
写它时,它不一定会立即在屏幕上打印字符。 一个例外是当stdout
连接到终端并且换行符是用printf
写的。 对于用户交互,这很好,因为用户会立即看到输出。 这就是大多数人在文本中打印换行符的原因。
如果你不这样做,但你仍然希望用户立即看到输出,那么这次你应该使用fflush
:
printf("What day is lesson %d?: ", i); fflush(stdout); scanf("%d", &give[0].day[i]);
我不知道是否保证scanf
在连接到终端时刷新stdout
,无论在最后不打印换行符时使用fflush(stdout)
都是好的做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.