使用数组进行 C 编程读写

标签 c arrays

我有一个程序,我应该在其中添加两个函数,这两个函数将从数组中读取元素并将其写入文件,以及从文件中读取并将信息放入数组中。

问题:

  1. saveFile(char *文件名); saveFile 函数将读取数组(person 目录)中的每个元素并将数据保存到磁盘文件中。

  2. loadFile(char *文件名); loadFile 函数将读取磁盘文件中的每个项目并将其加载到数组(person 目录)中。 loadFile 必须生成与 saveFile 函数读取的数据完全相同的数据结构和数据。

  3. 添加必要的代码来调用程序中的 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);
    }
}

最佳答案

fprintf 不是调用将结构输出到文件的正确函数,而且您无论如何都错误地使用了它。

文件句柄后面需要一个格式字符串,该字符串决定调用其余部分中的项目的格式。

你想要的函数是fwrite(和fread来取回它们)。它们完整地读取和写入底层数据。

例如,要编写整个 目录结构数组,您可以使用如下内容:

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");

关于使用数组进行 C 编程读写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28665816/

相关文章:

c++ - strcmp() 可以比较动态字符数组和静态字符数组吗?

c - 将数组传递给具有奇数格式的函数 - "v+last+1"

C++ 对齐和数组

C: Malloc 字符串数组混淆

java - C 服务器到 Java 客户端套接字读取以短值传递

java - 排序数组不同值总和到目标

c - 为什么 1/2 in c = -2010232232?

c - 在 C 中输入日期作为字符,无法弄清楚如何避免/

java - 数组列表打印奇怪的输出

javascript - 在 Javascript 文件中使用 AngularJS 过滤数组