我有一个程序,我应该在其中添加两个函数,这些函数将从数组中读取元素并将它们写入文件,并从文件中读取并将信息放入数组中。
问题:
saveFile(char * fileName); saveFile函数将读取数组中的每个元素(person目录)并将数据保存到磁盘文件中。
loadFile(char * fileName); loadFile函数将读取磁盘文件中的每个项目并将其加载到数组(person目录)中。 loadFile必须生成与saveFile函数读取的数据结构和数据完全相同的数据结构。
添加必要的代码来调用程序中的safeFile和loadFile函数,包括:声明全局文件名myDatabase;在存在main函数之前调用saveFile(myDatabase)来保存数据;在main函数的开头调用loadFile(myDatabase)将数据加载回person目录数组
到目前为止,这是我提出的:
void saveFile(char *fileName) {
FILE *fPointer;
fPointer = fopen(fileName, "w");
fprintf(fPointer, directory);
fclose(fPointer);
}
void loadFile(char *fileName) {
FILE *fPointer;
fPointer = fopen(fileName, "r");
while (!feof(fPointer)) {
fgets(directory, MAX, fPointer);
puts(directory);
fclose(fPointer);
}
}
我对阅读和编写文件只有基本的了解。我的程序符合要求,但每当我运行它时,都不会创建一个应该包含数组中值的文件。如果有人可以解释我如何使用上面的代码来正确地实现它,并提供给我的代码,那将是非常棒的!
以下是整个代码:
/**
Course: CSE240
Instructor: Dr. Chen
Assignment Name: Homework 4 Solution
Solved by: Garrett Gutierrez 2/7/2015
**/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#pragma warning(disable: 4996)
#define MAX 100
// Changed: deploma to diploma.
typedef enum { diploma = 0, bachelor, master, doctor } education;
// A struct to hold attributes of a person
struct person {
char name[30];
char email[30];
int phone;
education degree;
};
/******************* Global Variable Section *******************/
struct person directory[MAX]; // an array of structures, 100 entries
int tail = 0; // global variable
/******************* Foward Declaration Section *******************/
void branching(char c);
int delete_person();
void flush();
int insertion();
int print_person(int i);
int print_all();
int search_person();
void shift_data(char* name, char* email, int phone, education educationLevel);
int main()
{
// Print a menu for selection
char ch = 'i';
ungetc('\n', stdin); // Inject the newline character into input buffer
do {
printf("Enter your selection\n");
printf("\ti: insert a new entry\n");
printf("\td: delete an entry\n");
printf("\ts: search an entry\n");
printf("\tp: print all entries\n");
printf("\tq: quit \n");
flush(); // Flush the input buffer. To be discussed later
ch = tolower(getchar()); // Convert any uppercase char to lowercase.
branching(ch);
} while (ch != 113); // 113 is 'q' in ASCII
return 0;
};
// Flush the input buffer. To be discussed later
void flush()
{
int c;
do {
c = getchar();
} while (c != '\n' && c != EOF);
};
// Branch to different tasks: insert a person, search for a person, delete a person
// print all added persons.
void branching(char c)
{
switch (c) {
case 'i':
insertion();
break;
case 's':
search_person();
break;
case 'd':
delete_person();
break;
case 'p':
print_all();
break;
case 'q':
break;
default:
printf("Invalid input\n");
}
};
// Inserts the person lexigraphically. Note: A < a so all capital letters will be ordered first.
int insertion()
{
education educationLevel = 0;
char name[MAX], email[MAX];
int i = 0, phone;
// Case 1: The structure is filled.
if (tail == MAX) {
printf("There are no more places to insert.\n");
return -1;
}
// Case 2: The structure still has unfilled slots.
else
{
printf("Enter the name:\n");
scanf("%s", name);
printf("Enter the phone number:\n");
scanf("%d", &phone, sizeof(directory[tail].phone));
printf("Enter the e-mail:.\n");
scanf("%s", email);
//********** Question 1 ************
do {
printf("Enter the degree: select 0 for diploma, select 1 for bachelor, select 2 for master, or select 3 for doctor:\n");
scanf("%d", &educationLevel);
if (educationLevel < diploma || educationLevel > doctor)
{
printf("Please enter a value from 0 to 3.\n");
}
} while (educationLevel < diploma || educationLevel > doctor);
//**********************************************
//********* Question 2 ************
shift_data(name, email, phone, educationLevel);
//*****************************************
tail++;
printf("The number of entries = %d\n", tail);
}
return 0;
};
// Print the name, e-mail, phone, and education level of one person in the directory
int print_person(int i)
{
printf("\n\nname = %s\n", directory[i].name);
printf("email = %s\n", directory[i].email);
printf("phone = %d\n", directory[i].phone);
//************ Question 1 ******************
switch (directory[i].degree)
{
case diploma:
printf("degree = diploma\n");
break;
case bachelor:
printf("degree = bachelor\n");
break;
case master:
printf("degree = master\n");
break;
case doctor:
printf("degree = doctor\n");
break;
default:
printf("System Error: degree information corruption.\n");
break;
}
//****************************************
return 0;
}
// Print the name, e-mail, phone, and education level of each person in the directory
int print_all()
{
int i;
//Case 1: The structure is empty
if (tail == 0)
{
printf("No entries found.");
}
// Case 2: The structure has at least one item in it
else
{
for (i = 0; i < tail; i++) {
print_person(i);
}
printf("\n");
}
return 0;
};
//********** Question 3 **************
//Find a person by comparing names.
int search_person()
{
char sname[30];
int i = 0;
struct person* iterator = directory;
printf("Please enter the name to be searched for:\n");
scanf("%s", sname); //sname is an array, no & needed
while (i < tail)
{
if (strcmp(sname, iterator->name) == 0)
{
print_person(i);
return i;
}
iterator++;
i++;
}
printf("The name does not exist.\n");
return -1;
};
//***************************************
// Delete a person after finding that person via their name.
int delete_person()
{
int i, k;
k = search_person();
// Case 1: The person is not in the directory
if (k == -1)
{
printf("The name does not exist.\n");
return -1;
}
// Case 2: The person was found in the directory
else {
for (i = k; i<tail; i++)
{
strcpy(directory[i].name, directory[i + 1].name);
directory[i].phone = directory[i + 1].phone;
strcpy(directory[i].email, directory[i + 1].email);
printf("The index deleted is: %d\n", k);
}
tail--;
return k;
}
};
void shift_data(char* name, char* email, int phone, education educationLevel)
{
int i = 0, j = 0;
// Case 1: Empty List
if (tail == 0)
{
strcpy(directory[tail].name, name);
strcpy(directory[tail].email, email);
directory[tail].phone = phone;
directory[tail].degree = educationLevel;
return;
}
while (i < tail)
{
// Case 2: Beginning or middle of list
if (strcmp(name, directory[i].name) < 0)
{
j = tail;
while (j > i)
{
strcpy(directory[j].name, directory[j - 1].name);
strcpy(directory[j].email, directory[j - 1].email);
directory[j].phone = directory[j - 1].phone;
directory[j].degree = directory[j - 1].degree;
j--;
}
strcpy(directory[i].name, name);
strcpy(directory[i].email, email);
directory[i].phone = phone;
directory[i].degree = educationLevel;
return;
}
i++;
}
// Case 3: End of list
strcpy(directory[tail].name, name);
strcpy(directory[tail].email, email);
directory[tail].phone = phone;
directory[tail].degree = educationLevel;
};
void saveFile(char *fileName) {
FILE *fPointer;
fPointer = fopen(fileName, "w");
fprintf(fPointer, directory);
fclose(fPointer);
}
void loadFile(char *fileName) {
FILE *fPointer;
fPointer = fopen(fileName, "r");
while (!feof(fPointer)) {
fgets(directory, MAX, fPointer);
puts(directory);
fclose(fPointer);
}
}
答案 0 :(得分:0)
fprintf
不是调用结构输出到文件的正确函数,无论如何你都错误地使用它。
在文件句柄之后需要一个格式字符串,用于决定如何格式化其余调用中的项目。
您想要的功能是fwrite
(以及fread
让他们回来)。它们完整地读取和写入基础数据。
例如,要编写整个 directory
结构数组,您可以使用以下内容:
size_t written = fwrite (directory, sizeof (directory), 1, fPointer);
if (written != 1) puts ("Something went horribly wrong");
除了使用fread
代替fwrite
之外,阅读它几乎是一样的。
这可能是最简单的方法,但是,由于它读取和写入整个数组,因此就磁盘空间而言,它并不是最有效的。你可以零碎地做,一次只有一条记录,但这会引入代码复杂性,对于一个100元素的数组来说可能并不是必需的。
如果你选择存储整个数组,你可能也想要保存tail
,这样你就可以记住数组中有多少项正在使用中:
size_t written = fwrite (&tail, sizeof (tail), 1, fPointer);
if (written != 1) puts ("Something went horribly wrong");
答案 1 :(得分:-1)
void loadFile(char *myDatabase)
{
FILE *fileBuffer = fopen(myDatabase, "rb");
if (fileBuffer != NULL)
{
fread(&tail, sizeof(tail), 1, fileBuffer);
for (int i = 0; i < tail; i++)
{
fread(directory[i].name, sizeof(directory[i].name), 1, fileBuffer);
fread(&directory[i].phone, sizeof(&directory[i].phone), 1, fileBuffer);
fread(directory[i].email, sizeof(directory[i].email), 1, fileBuffer);
fread(&directory[i].degree, sizeof(&directory[i].degree), 1, fileBuffer);
}
fclose(fileBuffer);
}
这就是我对相同代码所拥有的......