注册 登录
编程论坛 闲聊灌水

【平安夜散分】武偉進

TonyDeng 发布于 2015-12-24 21:22, 5108 次点击
程序代码:

#include <cstdio>
#include <cstdlib>
#include "common.h"
#include "database.h"

/*
Field Student_Fields[] = {
    { "学号", 'I', 4, 0 },
    { "姓名", 'C', 30, 0 },
    { "性别", 'C', 1, 0 },
    { "年龄", 'I', 2, 0 },
    { "身份证", 'C', 18, 0 },
    { "联系电话", 'C', 20, 0 },
    { "地址", 'C', 50, 0 }
};
Header Student_Header = { _countof(Student_Fields), Student_Fields };
*/

Header Student_Header;

void List_Fields(const Header* header);

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        printf_s("命令格式: %s 数据文件名\n", Get_FileName(argv[0]));
        Pause();
        return EXIT_FAILURE;
    }

    FILE* file;
    if (fopen_s(&file, argv[1], "rt") == 0)
    {
        Load_Header(file, &Student_Header);
        fclose(file);
        List_Fields(&Student_Header);
    }
    //Create_Table(argv[1], &Student_Header);

    Pause();
    return EXIT_SUCCESS;
}

void List_Fields(const Header* header)
{
    size_t index;
    for (index = 0; index < header->Field_Number; ++index)
    {
        printf_s("%s  %c  %d,%d\n",
            header->Fields[index].Name,
            header->Fields[index].Type,
            header->Fields[index].Length,
            header->Fields[index].Decimal);
    }
}

只有本站会员才能查看附件,请 登录
33 回复
#2
TonyDeng2015-12-24 21:27
程序代码:

bool Load_Header(FILE* file, Header* header)
{
    char buffer[1024];
    bool success = true;

    rewind(file);
    bool inHeader = false;
    while (!ferror(file) && !feof(file) && fgets(buffer, _countof(buffer), file))
    {
        if (!inHeader)
        {
            _strupr_s(buffer, _countof(buffer));
            if (strcmp(buffer, "[HEADER]\n") == 0)
            {
                inHeader = true;
                continue;
            }
        }
        if (inHeader)
        {
            sscanf_s(buffer, "Fields Number: %u", &header->Field_Number);
            header->Fields = (Field*)calloc(header->Field_Number, sizeof(Field));
            if (header->Fields)
            {
                for (size_t index = 0; index < header->Field_Number; ++index)
                {
                    if (fgets(buffer, _countof(buffer), file))
                    {
                        Get_String(buffer, header->Fields[index].Name, sizeof(header->Fields[index].Name), '\"');
                        const char* p = strchr(buffer, '=');
                        if (p)
                        {
                            sscanf_s(p + 1, "%1c", &header->Fields[index].Type, 1);
                        }
                        else
                        {
                            header->Fields[index].Type = 'U';
                        }
                        p = strchr(buffer, '[');
                        if (!p || (sscanf_s(p, "[%d,%d]", &header->Fields[index].Length, &header->Fields[index].Decimal) != 2))
                        {
                            success = false;
                            break;
                        }
                    }
                    else
                    {
                        header->Field_Number = index;
                        success = false;
                        break;
                    }
                }
            }
            break;
        }
    }

    return success;
}


[此贴子已经被作者于2015-12-24 21:42编辑过]

#3
诸葛欧阳2015-12-24 21:48
啥意思⊙_⊙
#4
醒山2015-12-24 21:53
不明觉厉
#5
TonyDeng2015-12-24 21:57
程序代码:

#pragma once

// 字段結構
struct Field
{
    char Name[20];            // 名稱
    char Type;                // 類型
    int  Length;            // 長度
    int  Decimal;            // 小數位
};

// 表頭結構
struct Header
{
    size_t Field_Number;    // 字段數
    Field* Fields;            // 字段列表
};

// 用指定的結構建立數據表文件
errno_t Create_Table(const char* tableName, const Header* header);

// 從文件中讀取表頭
bool Load_Header(FILE* file, Header* header);
#6
tlliqi2015-12-24 22:14
科普呢?
#7
TonyDeng2015-12-24 22:15
教他如何讀文件
#8
TonyDeng2015-12-24 22:25
寫出去是這樣:
程序代码:

void Write_Header(FILE* file, const Header* header)
{
    fprintf_s(file, "%s\n", "[Header]");
    fprintf_s(file, "Fields Number: %u\n", header->Field_Number);
    for (size_t index = 0; index < header->Field_Number; ++index)
    {
        fprintf_s(file, "\"%s\"", header->Fields[index].Name);
        fprintf_s(file, "=%c[%d,%d]\n", header->Fields[index].Type, header->Fields[index].Length, header->Fields[index].Decimal);
    }
}
#9
TonyDeng2015-12-24 22:27
這是用文本格式的寫法,比較複雜,效率也低一點的。不過改用二進値格式的話,數據結構不用變化,在內部仍然是一樣的數據組織。

[此贴子已经被作者于2015-12-24 22:30编辑过]

#10
hellovfp2015-12-25 01:11
码了多少行代码了?如果用户写了写数据进去,要删除,添加些字段肿么办?还有用户一不小心修改到表头数据?

[此贴子已经被作者于2015-12-25 01:15编辑过]

#11
不懂才问2015-12-25 08:07
接分
#12
TonyDeng2015-12-25 09:26
以下是引用hellovfp在2015-12-25 01:11:39的发言:

码了多少行代码了?如果用户写了写数据进去,要删除,添加些字段肿么办?还有用户一不小心修改到表头数据?


1.就現在看到那麽多行代碼
2.表頭寫爲明文祇是方便看而已,確實難以阻攔用戶更改結構,事實上就算像DBF文檔那樣寫成二進制格式,也無法阻擋,有心總能改得到
3.頂多做到儘量的容錯。

下面是修改了一些bug之後的結果,容許一些空行、一些空格。
程序代码:

bool Load_Header(FILE* file, Header* header)
{
    char buffer[1024];
    bool success = true;

    bool inHeader = false;
    while (success && !ferror(file) && !feof(file) && fgets(buffer, _countof(buffer), file))
    {
        if (*Str_Trim(buffer) == '\n')
        {
            continue;
        }
        if (!inHeader)
        {
            _strupr_s(buffer, _countof(buffer));
            if (strcmp(buffer, "[HEADER]\n") == 0)
            {
                inHeader = true;
                continue;
            }
        }
        if (inHeader)
        {
            sscanf_s(buffer, "Fields Number: %u", &header->Field_Number);
            header->Fields = (Field*)calloc(header->Field_Number, sizeof(Field));
            if (header->Fields)
            {
                size_t index = 0;
                while ((index < header->Field_Number) && fgets(buffer, _countof(buffer), file))
                {
                    if (*Str_Trim(buffer) != '\n')
                    {
                        Get_String(buffer, header->Fields[index].Name, sizeof(header->Fields[index].Name), '\"');
                        const char* p = strchr(buffer, '=');
                        if (p)
                        {
                            sscanf_s(p + 1, " %1c", &header->Fields[index].Type, 1);
                        }
                        else
                        {
                            header->Fields[index].Type = 'U';
                        }
                        p = strchr(buffer, '[');
                        if (!p || (sscanf_s(p, "[%d,%d]", &header->Fields[index].Length, &header->Fields[index].Decimal) != 2))
                        {
                            success = false;
                            break;
                        }
                        ++index;
                    }
                }
            }
            break;
        }
    }

    return success;
}


只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2015-12-25 09:27编辑过]

#13
佳L2015-12-25 10:54
#14
hellovfp2015-12-25 11:06
回复 12楼 TonyDeng
表头数据做成xml格式如何?呵.呵,
其实这几天俺又查了一下目前数据库使用情况,
大致甲古文,MySql,MSSQL在世界排名前三,access数据库也在排名前面。
不过前二个都有闭源商业化的趋势,微软的使终有版权问题。连vs express版1个月都要过期,我去。

想弄个网络游戏数据做存储,靠这些商业数据库还真的不靠谱,
非要自己开弄数据库永久无版权之争?老T有什么想法没有?有相关书籍资料木有?

#15
TonyDeng2015-12-25 11:41
xml的读写器在.net中才有,自己写不现实。小型的数据管理,自己写就可以了,用不着数据库。

[此贴子已经被作者于2015-12-25 11:42编辑过]

#16
hellovfp2015-12-25 12:45
回复 15楼 TonyDeng
汗,XML什么.net才有哦,直接调用com接口就完了。其它XML解析库也有很多。
其实你这个构思,倒是真的给俺一些想法,字段内容搜索用文件指针挺方便的。
如果自己用做网络数据库,也不需要太麻烦的速度需求,可以满足需求,又避免了版权问题。

就等你码好了,怎么样?哈哈
#17
TonyDeng2015-12-25 12:49
不用第三方解析库
#18
谁与争疯2015-12-25 12:58
太长不看。
#19
hellovfp2015-12-25 13:00
赶紧继续码代码,呵.呵。。。估计武同学看到你的代码要死了一半,要简单易懂,易懂哈!
做好了,俺帮你拿cppcheck检查一下可能潜在的问题。

[此贴子已经被作者于2015-12-25 13:08编辑过]

#20
TonyDeng2015-12-25 13:42
很難看嗎?
#21
hellovfp2015-12-25 13:52
疯姐不看代码的。刚好巡山到这里。
#22
yuccn2015-12-25 18:03
以下是引用醒山在2015-12-24 21:53:56的发言:

不明觉厉

#23
hu9jj2015-12-25 18:56
凑热闹。
#24
武伟2015-12-25 19:03
以下是引用hellovfp在2015-12-25 13:00:28的发言:

赶紧继续码代码,呵.呵。。。估计武同学看到你的代码要死了一半,要简单易懂,易懂哈!
做好了,俺帮你拿cppcheck检查一下可能潜在的问题。

想说的是hello您高估我了——我已经阵亡

[此贴子已经被作者于2015-12-25 19:17编辑过]

#25
TonyDeng2015-12-25 20:24
陣亡了?
#26
wmf20142015-12-25 20:30
想做有中国版权的数据库系统,就应该跳出固有的数据库概念,否则就是低级重复研发。
就像农民做飞机。飞机其实已经不是高科技了,而农民的水平是很难让做飞机的工艺水平得到根本性提高,那他做出来的飞机永远只是个小玩意,是败家、浪费生命的行为
#27
武伟2015-12-25 20:47
是不是 "common.h"和 "database.h"中的代码还没有贴上来?基本上是阵亡了,T版,对不起了
#28
TonyDeng2015-12-25 20:51
以下是引用武伟在2015-12-25 20:47:53的发言:

是不是 "common.h"和 "database.h"中的代码还没有贴上来?基本上是阵亡了,T版,对不起了

當然沒貼了,祇是讓你感受一下是這麽處理,不是直接給全部。函數的功能是可以從命名猜到的。
#29
武伟2015-12-25 20:59
小子我悟性太低,代码看不懂,具体怎么处理都没感受到,只能说看懂一点点

[此贴子已经被作者于2015-12-25 21:01编辑过]

#30
hellovfp2015-12-25 23:44
以下是引用wmf2014在2015-12-25 20:30:21的发言:

想做有中国版权的数据库系统,就应该跳出固有的数据库概念,否则就是低级重复研发。
就像农民做飞机。飞机其实已经不是高科技了,而农民的水平是很难让做飞机的工艺水平得到根本性提高,那他做出来的飞机永远只是个小玩意,是败家、浪费生命的行为


哈哈,中国人很有鲁迅先生说的拿来主义精神,用现成,俺也准备捡现成跳出固有概念基本不现实,sql语法早已成为事实上的国际通用标准。这么多年其实全球程序员写了不少重复功能的代码,什么时候大家统一为共同的目标写程序的时候,人类科技将会出现程序界的文艺复兴式的飞跃。
#31
hellovfp2015-12-25 23:58
回复 24楼 武伟
哈哈,这仗还木有开打,你就阵亡了,看来老T这代码炸弹的威力惊人。炸醒了木有?不急,估计你以后会明白的。数据库程序内部还是拿数据库来管理用户数据表的,比如mssql里的master表记录用户数据库表信息就和T版这示例代码中的结构差不多,查询这表就知道数据库有多少表,进一步还可以查每个表有多少字段,及字段大小,数据类型。程序的世界很精彩,慢慢玩吧。

[此贴子已经被作者于2015-12-26 00:00编辑过]

#32
TonyDeng2015-12-26 01:13
再复杂的数据库也是对文件操作,文件处理是编程基本功。
#33
hxfly2015-12-26 05:51
占楼,接分
#34
武伟2015-12-26 23:50
回复 31楼 hellovfp
谨记,受教
1