注册 登录
编程论坛 C++教室

文件信息的删除

love云彩 发布于 2013-06-17 13:34, 1292 次点击
创建了一个空的TXT文件,然后写一个类,创建几个类对象,将类对象的信息储存到TXT文件里,
如果我想删除某一个对象的信息,应该怎样编写一个函数来删除文件里面的某一个类对象的信息?
17 回复
#2
love云彩2013-06-17 19:41
该不会没人懂??求帮忙啊
#3
TonyDeng2013-06-17 21:08
没看懂你的问题
#4
我有我梦2013-06-17 21:49
不知道什么意思!
#5
love云彩2013-06-18 01:24
好吧!等我明天考完试,我再跟你细说
#6
love云彩2013-06-19 11:16
只有本站会员才能查看附件,请 登录

我在TXT文件里输入以上的信息,要想根据工号来删除某个职工人员的信息(比如说删除工号为111的职工人员的信息),怎么实现删除这个功能
#7
TonyDeng2013-06-19 11:58
要单纯达到你所说的目的,有很多种方法,看你原先设计的思路是怎样的了。
#8
love云彩2013-06-19 12:25
回复 7楼 TonyDeng
我的设计思路是:1、创建一个类,然后创建几个对象并初始化以上截图那些信息。
2、新建一个TXT文档,将类对象的所有信息写入文档里面储存。
3、编写一个删除信息的函数,在程序运行的时候,根据输入的工号来删除某一个职工的信息。
4、删除完成后,其他职工的信息依旧不变,还是保存在TXT文档里面
整个过程不出现链表,不能用链表来实现数据的删除,就是有这样的条件限制,我才不知道怎么下手,
而且文件操作那个部分我不是很精通,所以不知道怎么删除文档里面的某一个数据
#9
TonyDeng2013-06-19 12:30
无需用链表,结构体数组就可以了。文件读写是把数据读到内存中整理好重新写一次即可,因为预期的数据量不大,可以了,如果数据量大,要分步读写,或者用标志删除法。
#10
love云彩2013-06-19 12:37
以下是引用TonyDeng在2013-6-19 12:30:28的发言:

无需用链表,结构体数组就可以了。文件读写是把数据读到内存中整理好重新写一次即可,因为预期的数据量不大,可以了,如果数据量大,要分步读写,或者用标志删除法。
能不能就我给出的那几个职工信息演示一遍怎样实现删除信息吗?例子最能帮助我,还有,那些职工是用类来创建对象的,用结构体数组起到什么作用?不明白
#11
TonyDeng2013-06-19 12:59
过几天写给你看吧
#12
love云彩2013-06-19 13:23
回复 11楼 TonyDeng
好的,正好这几天我也忙着复习考试,等你忙完了再写也不急
#13
love云彩2013-06-20 02:07
回复 9楼 TonyDeng
版主记得回复我啊,千万别忽悠我,我可等你的例子给我解释一下呢
#14
TonyDeng2013-06-20 21:43
会给你的,放心。
#15
TonyDeng2013-06-25 04:04
main.cpp
程序代码:

/*
    题目来源:
<span style="color: #008000; text-decoration: underline;">https://bbs.bccn.net/thread-415375-1-1.html[/color]
    编程环境:Visual Studio 2012 C++
    2013.06.25
*/

#include <cstdio>
#include <cstdlib>
#include <vector>
#include <conio.h>
#include "Employee.h"

void Pause(void);
bool Init(void);

const char* file_name = "data.txt";

void main(void)
{
    // 构建原始数据
    Init();

    printf_s("文件中的原始数据\n");
    std::vector<Employee*> employees = Employee::Load_Data(file_name);
    Employee::List(employees);

    Pause();

    // 删除一条记录并储存到文件中
    employees[1]->Delete();
    Employee::Save_Data(file_name, employees, 0, employees.size());

    printf_s("\n\n删除后的数据\n");
    Employee::List(Employee::Load_Data(file_name), false);

    Pause();
}

void Pause(void)
{
    printf_s("\nPress any key to continue...");
    _getch();
}

// 生成原始数据文件
bool Init(void)
{
    Employee* employees[] = {
        new Employee(110, 1, "张三", 25, 1900),
        new Employee(111, 2, "李四", 28, 1700),
        new Employee(112, 3, "王五", 30, 1900)
    };
    FILE* file;
    errno_t error_code = fopen_s(&file, file_name, "wb");
    if (error_code != 0)
    {
        printf_s("File %s open error: %d\n", file_name, error_code);
        return false;
    }
    for (size_t index = 0; index < _countof(employees); ++index)
    {
        Employee::Write_Record(*employees[index], file);
    }
    fclose(file);
    return true;
}


Employee.h
程序代码:

#ifndef _EMPLOYEE
#define _EMPLOYEE

class Employee
{
private:

    bool _deleted;      // 删除标志
    int _id;            // 工号
    int _type;          // 职工类型
    char _name[20];     // 姓名
    int _age;           // 年龄
    int _pay;           // 工资

public:

    Employee();
    Employee(int id, int type, const char* name, int age, int pay);

    void Display(void);
    const char* const ToString(void);
    void Delete(void);
    void Recall(void);
    bool IsDeleted(void);

    static Employee* Read_Record(FILE* file);
    static void Write_Record(Employee& record, FILE* file);
    static std::vector<Employee*> Load_Data(const char* file_name);
    static bool Save_Data(const char* file_name, std::vector<Employee*> employees, int start, size_t count);
    static void List(std::vector<Employee*>& employees, bool show_deleted = true);
};

#endif


Employee.cpp
程序代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include "Employee.h"

static const char* Employee_Type[] = {
    "教师",
    "临时教师",
    "主任"
};

Employee::Employee()
{
    _deleted = false;
    _id = 0;
    _type = 0;
    _name[0] = '\0';
    _age = 0;
    _pay = 0;
}

Employee::Employee(int id, int type, const char* name, int age, int pay)
{
    _deleted = false;
    _id = id;
    _type = type;
    strncpy_s(_name, name, sizeof(_name) - 1);
    _age = age;
    _pay = pay;
}

void Employee::Display(void)
{
    printf_s("工号: %03d\n", _id);
    printf_s("类型: %s\n", Employee_Type[_type - 1]);
    printf_s("姓名: %s\n", _name);
    printf_s("年龄: %d\n", _age);
    printf_s("工资: %d\n\n", _pay);
}

const char* const Employee::ToString(void)
{
    const size_t buffer_size = 100;
    char* buffer = new char[buffer_size];
    if (buffer != nullptr)
    {
        sprintf_s(buffer, buffer_size, "%c%03d %-10s %-20s %2d %6d", _deleted ? '*' : ' ', _id, Employee_Type[_type - 1], _name, _age, _pay);
    }
    return buffer;
}

void Employee::Delete(void)
{
    _deleted = true;
}

void Employee::Recall(void)
{
    _deleted = false;
}

bool Employee::IsDeleted(void)
{
    return _deleted;
}

Employee* Employee::Read_Record(FILE* file)
{
    Employee* e = new Employee;
    if ((e == nullptr) || fread(e, sizeof(Employee), 1, file) != 1)
    {
        e = nullptr;
    }
    return e;
}

void Employee::Write_Record(Employee& record, FILE* file)
{
    fwrite(&record, sizeof(Employee), 1, file);
}

std::vector<Employee*> Employee::Load_Data(const char* file_name)
{
    std::vector<Employee*> employees;
    FILE* file;
    errno_t error_code = fopen_s(&file, file_name, "rb");
    if (error_code == 0)
    {
        Employee* e;
        while (e = Employee::Read_Record(file))
        {
            employees.push_back(e);
        }
        fclose(file);
    }
    else
    {
        printf_s("File %s open error: %d\n", file_name, error_code);
    }
    return employees;
}

bool Employee::Save_Data(const char* file_name, std::vector<Employee*> employees, int start, size_t count)
{
    bool result(true);
    FILE* file;
    errno_t error_code = fopen_s(&file, file_name, "wb");
    if (error_code != 0)
    {
        printf_s("File %s create error: %d\n", file_name, error_code);
        result = false;
    }
    for (size_t index = start; index < start + count; ++index)
    {
        Employee::Write_Record(*employees[index], file);
    }
    fclose(file);
    return result;
}

void Employee::List(std::vector<Employee*>& employees, bool show_deleted)
{
    for (std::vector<Employee*>::const_iterator iterator = employees.cbegin(); iterator != employees.cend(); ++iterator)
    {
        if (!(*iterator)->IsDeleted() || show_deleted)
        {
            const char* const buffer = (*iterator)->ToString();
            printf_s("%s\n", buffer);
            delete buffer;
        }
    }
}
#16
TonyDeng2013-06-25 10:44
补充:
1.其实Load_Data()、Save_Data()和List()方法,可以不放在Employee类中,因为它与对象的具体组织形式有关;
2.在Windows系统中的程序,可以不释放动态分配的内存,系统会保证在程序结束后收回,所以在这里并没有对所有动态分配的内存都写释放代码。
#17
love云彩2013-06-25 12:52
回复 16楼 TonyDeng
真的非常感谢,我先拿去参考一下了!很有价值
#18
TonyDeng2013-06-25 13:05
把那三个方法搬回main.cpp中吧,我原先就是在那里的,后来手痒改成这样(看看代码就知道了,出现类引用表明原先是在外部的),发帖后就后悔了。

我之所以改了你原先用文本格式储存数据,是因为用scanf()系列读字符串时会被空格干扰,又懒得写定长格式的读写代码,就用了二进制储存格式,你可以自己改回去的,反正原理就那么回事。写得匆忙,有很多东西还可以改进的,自己琢磨吧,现在分解的函数已考虑到将来各种变化需求了。

[ 本帖最后由 TonyDeng 于 2013-6-25 13:06 编辑 ]
1