我试图编写一个程序,从用户那里获取n个学生,将它们存储在一个结构中,然后将它们存储在一个文件中。
当我尝试将元素存储在文件中时,它似乎只是收集了名称和大量垃圾。
我认为问题可能是我如何分配内存,但我不确定。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
char name[32];
int number;
float gpa;
}sArray[100];
//Global variables
int totalStudents;
int i;
//Reads From the User
//a number of records to read
//b all records (name, number, gpa)
//c return list of students - TODO!
struct Student getStudents(){
//Get number of elements
printf("Enter Number of Students: ");
scanf("%d", &totalStudents);
sArray[totalStudents];
printf("You Entered: %d\n", totalStudents);
for(i=0;i<totalStudents;i++){
printf("Enter Student %d Name: \n", i+1);
scanf("%s", sArray[i].name);
printf("Enter Student %d Number: \n", i+1);
scanf("%d", &sArray[i].number);
printf("Enter Student %d GPA: \n", i+1);
scanf("%f", &sArray[i].gpa);
}
//Allocate memory
struct Student *ptr;
ptr = (struct Student*) malloc(totalStudents * sizeof(struct Student));
free(ptr);
}
//Writes records to a File called student.db
int writeToFile(){
FILE *fp;
if((fp = fopen("student.db", "wb")) == NULL){
puts("Error, File Could Not Be Opened.");
}
else{
for(i=0;i<totalStudents;i++){
fwrite(&sArray[i], sizeof(sArray[i]), 1, fp);
}
}
fclose(fp);
}
//Switch Function - TODO!
//Print Function
struct Student displayStudents(){
for(i=0;i<totalStudents;i++){
printf("%s %d %.2f\n", sArray[i].name, sArray[i].number, sArray[i].gpa);
}
}
//Main
int main(){
getStudents();
writeToFile();
displayStudents();
return 0;
}
如果我的输入值为{1,Dychii,123,4},则将其写入文件:
答案 0 :(得分:1)
无论你在struct中的名字有多长,它都会为int的4个字节写入32个字符,为float写4个字节。字符串中的null终止符后面的字符不匹配。在你的情况下&#34; Dychii \ 0&#34; 7个字符,之后25个字符并不重要。
顺便而不是
fwrite(&sArray[i], sizeof(sArray[i]), 1, fp);
你可以说
fwrite(&sArray[i], sizeof(Student), 1, fp);
稍微更具可读性。
答案 1 :(得分:0)
您正在写入二进制文件。这意味着您创建的文件与数据存储在内存中的方式相同。这也意味着您无法在普通编辑器中打开文件并对其有任何意义。使用十六进制编辑器,如果您知道变量如何存储在内存中,您可能能够理解它。
如果您想以文本模式存储文件,以便可以在普通编辑器中打开它,您可以尝试这样的事情:
//Writes records to a File called student.db
void writeToFile(){
FILE *fp;
if((fp = fopen("student.db", "w")) == NULL){ //Note: only w
puts("Error, File Could Not Be Opened.");
}
else{
for(i=0;i<totalStudents;i++){
fprintf(fp, "%s ", sArray[i].name);
fprintf(fp, "%d ", sArray[i].number);
fprintf(fp, "%f\n", sArray[i].gpa);
}
}
fclose(fp);
}
除此之外,您还有一些代码问题:
1)sArray[totalStudents];
无效 - 只需删除它
2)即使你说他们应该,函数getStudents
,writeToFile
和displayStudents
也不会返回任何内容。也许你真的希望它们是void
动态内存
你说你想使用动态内存。但目前你没有。这段代码:
//Allocate memory
struct Student *ptr;
ptr = (struct Student*) malloc(totalStudents * sizeof(struct Student));
free(ptr);
分配一些内存然后再次释放它。换句话说 - 代码什么都不做。事实上,您目前只使用全球sArray
所有地方。
如果要使用动态内存,则应首先进行此更改:
struct Student {
char name[32];
int number;
float gpa;
}; // Get rid of global variable sArray[100];
然后,您需要更改当前使用sArray
的其余代码中的所有位置。
一个例子:
struct Student* getStudents(){ // Return a pointer to struct Student
//Get number of elements
printf("Enter Number of Students: ");
scanf("%d", &totalStudents);
printf("You Entered: %d\n", totalStudents);
// Allocate memory
struct Student* ptr;
ptr = malloc(totalStudents * sizeof(struct Student));
for(i=0;i<totalStudents;i++){
printf("Enter Student %d Name: \n", i+1);
scanf("%s", ptr[i].name);
printf("Enter Student %d Number: \n", i+1);
scanf("%d", &(ptr[i].number));
printf("Enter Student %d GPA: \n", i+1);
scanf("%f", &(ptr[i].gpa));
}
return ptr; // Return a pointer to struct Student
}
希望这能为您提供更新其他代码部分的想法。
最终评论:您应该添加错误检查。那是
a)始终检查scanf
b)始终检查malloc