文件目录管理与显示

时间:2020-11-30 16:59:53

文件目录管理与显示
给出目录和文件信息,编程实现将其排列成一棵有一定缩进的树。
要求:
(1)设计文件和目录信息树的存储结构。
(2)从文件或键盘输入目录和文件信息,输入格式采用绝对路径法,即:
\A
\A\AA1
\A\AA1\aa1.doc

创建时要检查同一路径下不能有同名的目录或文件名。
(3)设计文件和目录信息树的输出格式(以凹入表的形式显示)。
(4)查找指定目录和文件。
(5)添加新目录或新文件。
(6)删除指定目录或文件,子目录能够被删除的前提是其为空,既不包含任何子目录和文件;根目录不能删除。
(7)扩充目录或文件信息,如创建时间、读写权限、文件长度或子目录包含的子目录和文件数等。
(8)对同一层次下的子目录或文件按创建时间有序输出。
(9)通配符的使用。如用“?”代表任意一个字符,用“*”表示任意多个任意字符。
扩展内容:
实现相对路径表示法。

#include <stdio.h> 
#include <malloc.h> 
#include <string> 
#include <iostream> 
#include <sstream> 

using namespace std;  

#include "Sibtree.h" 

void add(SibTree *t1)  
{  
    printf("输入目录文件信息以输入0结束:\n");  
    SibTreeNode *r, *r1, *r2;  
    char ifm[1000] = { '\0' }, name1[50], name2[50];  
    char *str;  
    int i, j, n;  
    while (1)  
    {  
        cin >> ifm;  
        str = ifm;  
        if (*str == '0')break;  
        r = t1->root;  
        if (r == NULL)  
        {  
            for (i = 0, str += 1; *str != '\\'&&*str != '\0'; str++, i++)  
            {  
                name1[i] = *str;  
            }  
            name1[i] = '\0';  
            if (*str == '\0')insertRoot(t1, name1);  
            else  
                printf("%s的路径不存在,不能添加\n", name1);  
        }  
        else  
        {  
            for (i = 0, str += 1; *str != '\\'&&*str != '\0'; str++, i++)  
            {  
                name1[i] = *str;  
            }  
            name1[i] = '\0';  
            if (search(t1, name1) == 0 && *str == '\0')  
            {  
                insertnextSibing(t1, r, name1);  
            }  
            if (search(t1, name1) == 0 && *str != '\0')printf("%s的路径不存在,不能添加\n", name1);  
            r1 = LevelOrderTraverse(t1->root, name1);  
            while (r1 != NULL)  
            {  
                if (*str == '\0')break;  
                for (i = 0, str += 1; *str != '\\'&&*str != '\0'; str++, i++)  
                {  
                    name2[i] = *str;  
                }  
                name2[i] = '\0';  
                if (*str == '\0')  
                {  
                    if (insertChild(t1, r1, name2)){ break; }  
                }  
                else  
                {  
                    n = children(r1);  
                    for (j = 1; j <= n; j++)  
                    {  
                        if (strcmp(child(r1, j)->data, name2) == 0)break;  
                    }  
                    if (j <= n)r2 = child(r1, j);  
                    else r2 = NULL;  
                    if (r2 == NULL)printf("%s的路径不存在,不能添加\n", name2);  
                }  
                n = children(r1);  
                for (j = 1; j <= n; j++)  
                {  
                    if (strcmp(child(r1, j)->data, name2) == 0)break;  
                }  
                if (j <= n)r1 = child(r1, j);  
                else r1 = NULL;  
            }  
        }  
    }  
}  
void check(SibTree *t)  
{  
    SibTreeNode *r;  
    printf("输入要查找的文件名:");  
    char name[50];  
    cin >> name;  
    r = *1LevelOrderTraverse(t->root, name);  
    if (r == NULL)
        //printf("没有此文件\n");
        printf("\n");
    else  
    {  
        printf("此文件找到,创建时间为:");  
        printf("%d/%d/%d %d:%d:%d", r->year, r->month, r->day, r->hour, r->minute, r->second);  
        printf("\t子目录个数为:");  
        printf("%d\n", children(r));  
    }  
} 

void Delete(SibTree *t)  
{  
    SibTreeNode *r, *p, *kid;  
    printf("输入要删除的文件名:");  
    char name[50];  
    cin >> name;  
    r = LevelOrderTraverse(t->root, name);  
    if (r == NULL)printf("没有此文件!\n");  
    else  
    {  
        if (r->firstChild != NULL)printf("有子文件不能删除!\n");  
        else  
        {  
            p = r->parent;  
            kid = p->firstChild;  
            if (strcmp(kid->data, r->data) == 0)p->firstChild = kid->nextSibling;  
            else  
            {  
                while (strcmp(kid->nextSibling->data, r->data))kid = kid->nextSibling;  
                kid->nextSibling = kid->nextSibling->nextSibling;  
            }  
            printf("已删除!\n");  
        }  
    }  
}  
void out(SibTree *t)  
{  
    printf("输出文件目录的信息:\n");  
    printf("root:\n");  
    printf("%s", toString(t).c_str());  
}  
void repair(SibTree *t)//修改扩充  
{  
    SibTreeNode *r, *p, *kid;  
    printf("输入想要扩充或修改的文件或目录的名称\n");  
    char name[100];  
    cin >> name;  
    r = LevelOrderTraverse(t->root, name);  
    if (r == NULL)  
        printf("没有此文件!\n");  
    else  
    {  
        printf(" 查找成功\n\n 1 修改or 2扩充?\n\n\n");  
        int k;  
        cin >> k;  
        if (k == 1)  
        {  
            printf("输入目录或文件的新名称 \n");  
            char Name[100];  
            cin >> Name;  
            strcpy(r->data, Name);  
            printf(" 修改成功!\n\n");  
            printf(" 修改时间为:");  
            printf("%d年/%d月/%d%d时:%d分:%d秒\n\n\n", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond);  
            r->year = sys.wYear;  
            r->month = sys.wMonth;  
            r->day = sys.wDay;  
            r->hour = sys.wHour;  
            r->minute = sys.wMinute;  
            r->second = sys.wSecond;  
        }  
        else  
        {  
            printf("当前目录的信息为:\n 限制子目录的个数 %d 个 限制子文件的个数 %d 个\n", r->sonmulu, r->sonfile);  
            printf("请输入修改后的限制子目录的个数和限制子文件的个数:\n");  
            int a, b;  
            cin >> a >> b;  
            r->sonmulu = a;  
            r->sonfile = b;  
            printf("修改成功!\n\n\n");  
        }  
    }  
}  

void *check(SibTree *t)  
{  
    SibTreeNode *r;  
    printf("输入要查找的文件或目录名:");  
    char name[50];  
    cin >> name;  
    r = *LevelOrderTraverse(t->root, name);  
    if (r == NULL) //printf("没有此文件\n");  
        printf("\n");  
    else  
    {  
        printf("此文件或目录找到,创建时间为:");  
        printf("%d/%d/%d %d:%d:%d", r->year, r->month, r->day, r->hour, r->minute, r->second);  
        printf("\t子目录个数为:");  
        printf("%d\n", children(r));  
    }  
}  

void main()  
{  
    SibTree t1;  
    int k;  
    TreeInitiate(&t1);  
    while (1)  
    {  
        printf("\n");  
        printf("\t 文件管理 \t\n");  
        printf("\t********************************************************\t\n");  
        printf("\t *************对照号码输入你要进行的操作*************\n");  
        printf("\t 1 ——>添加目录或文件 \n");  
        printf("\t 2 ——>查找目录或文件 \n");  
        printf("\t 3 ——>删除目录或文件 \n");  
        printf("\t 4 ——>输出文件信息 \n");  
        printf("\t 5 ——>扩充目录或文件信息 \n");  
        printf("\t 6 ——>模糊查找 \n");  
        printf("\t 7 ——>退出 \n");  
        printf("输入你想进行的操作号码:");  
        scanf("%d", &k);  
        if (k == 7)break;  
        switch (k)  
        {  
        case 1: add(&t1); break;  
        case 2: check(&t1); break;  
        case 3: Delete(&t1); break;  
        case 4: out(&t1); break;  
        case 5: repair(&t1); break;  
        case 6: *check(&t1); break;  
        default:  
            printf("输入号码错误!\n");  
        }  
    }  
}  
#include <windows.h> 
#include <queue>
SYSTEMTIME sys;  
int ok;  
typedef struct SibTreeNode  
{  
    char data[50];  
    int valid;  
    int year;  
    int month;  
    int day;  
    int hour;  
    int minute;  
    int second;  
    int sonmulu;  
    int sonfile;  
    struct SibTreeNode * parent;  
    struct SibTreeNode *firstChild;  
    struct SibTreeNode *nextSibling;  
}SibTreeNode;  

typedef struct  
{  
    SibTreeNode *root;  
    int size;  
}SibTree;  

typedef SibTreeNode *QueueDataType;  
#include "SeqCQueue.h" 

int IsTreeEmpty(SibTree *t)  
{  
    return t->size == 0;  
}  

int isValidNode(SibTreeNode *p)  
{  
    if (p)  
        return p->valid;  
    else return 0;  
}  
//创建一个空树 
void  TreeInitiate(SibTree *t)  
{  
    t->root = NULL;  
    t->size = 0;  
}  

//创建结点 
SibTreeNode * newSibTreeNode(char x[50])  
{  
    GetLocalTime(&sys);  
    SibTreeNode *p = (SibTreeNode *)malloc(sizeof(SibTreeNode));  
    strcpy(p->data, x);  
    p->valid = true;  
    p->year = sys.wYear;  
    p->month = sys.wMonth;  
    p->day = sys.wDay;  
    p->hour = sys.wHour;  
    p->minute = sys.wMinute;  
    p->second = sys.wSecond;  
    p->sonmulu = 5;    //扩充的信息,限制子目录的个数 
    p->sonfile = 2;     //限制子文件的个数 
    p->parent = NULL;  
    p->firstChild = NULL;  
    p->nextSibling = NULL;  
    return  p;  
}  

//创建包含一个结点的树 
void onenodeSibTree(SibTree *t, char x[50])  
{  
    t->root = newSibTreeNode(x);  
    strcpy(t->root->data, x);  
    t->size = 1;  
}  

//输出当前结点的父亲节点 
SibTreeNode *root(SibTreeNode *p)  
{  
    if (p == NULL)  
    {  
        p = (SibTreeNode*)malloc(sizeof(SibTreeNode));  
        return p;  
    }  
    else  
    {  
        return p;  
    }  
}  
//插入根节点 
void insertRoot(SibTree *t, char x[50])  
{  
    SibTreeNode * newRoot = newSibTreeNode(x);  
    newRoot->firstChild = t->root;  
    if (t->root != NULL)  
    {  
        t->root->parent = newRoot;  
    }  
    t->root = newRoot;  
    t->size++;  
}  

// 输出树的大小 
int size(SibTree *t)  
{  
    return t->size;  
}  


// 构造一个不合法的结点 
SibTreeNode * invalidSibTreeNode()  
{  
    SibTreeNode *p = (SibTreeNode *)malloc(sizeof(SibTreeNode));  
    p->valid = false;  
    return  p;  
}  

//当前结点的孩子的个数 
int children(SibTreeNode *p)  
{  
    int count = 0;  
    SibTreeNode *countNode;  
    if (isValidNode(p))  
    {  
        countNode = p->firstChild;  
        while (countNode != NULL)  
        {  
            count++;  
            countNode = countNode->nextSibling;  
        }  
        return count;  
    }  
    else  
    {  
        return 0;  
    }  
}  

//返回当前结点的cth孩子结点 
SibTreeNode *child(SibTreeNode *p, int c)  
{  
    if (isValidNode(p))  
    {  
        if (c < 1)  
        {  
            return invalidSibTreeNode();  
        }  
        SibTreeNode *kid = p->firstChild;  
        while ((kid != NULL) && (c > 1))  
        {  
            kid = kid->nextSibling;  
            c--;  
        }  
        if (kid == NULL)  
        {  
            return invalidSibTreeNode();  
        }  
        else  
        {  
            return kid;  
        }  
    }  
    else  
        throw "the node is not a valid node!";  

}  

//返回当前结点的兄弟结点 
SibTreeNode *nextSibling(SibTreeNode *p)  
{  
    if (isValidNode(p))  
    {  
        if (p->nextSibling == NULL)  
        {  
            return invalidSibTreeNode();  
        }  
        else  
        {  
            return p->nextSibling;  
        }  
    }  
    else  
    {  
        throw "the node is not a valid node!";  
        return invalidSibTreeNode();  
    }  
}  

//插入孩子结点 
int insertChild(SibTree *t, SibTreeNode *p, char x[50])  
{  
    SibTreeNode *n;  
    int i, flog = 0;  
    for (i = 0; x[i] != '\0'; i++)  
    {  
        if (x[i] == '.'){ flog = 1; break; }  
    }  

    if (isValidNode(p))  
    {  
        n = p->firstChild;  
        if (n == NULL)  
        {  
            p->firstChild = newSibTreeNode(x);  
            p->firstChild->parent = p;  
        }  
        else  
        {  
            while (n != NULL)  
            {  
                if (strcmp(n->data, x) == 0){ printf("输入的文件有重名,请更改名字!"); break; }  
                if (n->nextSibling == NULL)break;  
                n = n->nextSibling;  
            }  
            if (strcmp(n->data, x) != 0)  
            {  
                if (flog == 1 && children(n->parent)<n->parent->sonfile)  
                {  
                    n->nextSibling = newSibTreeNode(x); n->nextSibling->parent = p;  
                }  
                else  
                    if (flog == 1)printf("文件数超出,不能继续存储\n");  
                    else  
                        if (flog == 0 && children(n->parent)<n->parent->sonmulu)  { n->nextSibling = newSibTreeNode(x); n->nextSibling->parent = p; }  
                        else if (flog == 0)printf("子目录超出,不能继续存储\n");  

            }  
        }  
        t->size++;  
        return 1;  
    }  
    else return 0;  
}  
//为当前结点插入兄弟结点 
int insertnextSibing(SibTree *t, SibTreeNode *p, char x[50])  
{  
    SibTreeNode *n;  
    if (isValidNode(p))  
    {  
        n = p->nextSibling;  
        if (n == NULL)p->nextSibling = newSibTreeNode(x);  
        else  
        {  
            while (n->nextSibling != NULL)n = n->nextSibling;  
            n->nextSibling = newSibTreeNode(x);  
            n->nextSibling->parent = p->parent;  
        }  
        t->size++;  
        return 1;  
    }  
    else return 0;  
}  

int *check(char a[], char b[])  
{  
    int len = strlen(b);  
    int len1 = strlen(a);  
    for (int i = 0; i < len; i++)  
    {  
        if (b[i] == '*')  
        {  
            int j = len - 1;  
            int k = len1 - 1;  

            while (j != i)  
            {  
                if (b[j] != a[k])  
                    return 0;  
                --j;   
                --k;  
            }  
            return 1;  
        }  
        else if (b[i] != '?')  
        {  
            if (a[i] != b[i])  
                return 0;  
        }  
    }  
    return 1;  
}  

//模糊查找 
SibTreeNode **LevelOrderTraverse(SibTreeNode *t, char a[50])  
{  
    int ok = 0;  
    SeqCQueue Q;  
    SibTreeNode *x;  
    if (t == NULL)return NULL;  
    QueueInitiate(&Q);  
    QueueAppend(&Q, t);  
    x = t->nextSibling;  
    while (x != NULL)  
    {  
        QueueAppend(&Q, x);  
        x = x->nextSibling;  
    }  
    while (QueueNotEmpty(Q))  
    {  
        QueueDelete(&Q, &x);  
        if (*check(x->data, a) == 1)  
        {  
            ok = 1;
            printf("查找到符合条件的有");//%s\n",x->data);
            ////////
            SibTreeNode *xx;
            xx = x;



            char sss[100][100];
            char gan = '\\';
            int len = 0;
            while (xx!=root(t) )//&& xx->parent != NULL)
            {
                strcpy(sss[len++],xx->data);
                //printf("\%s ",xx->data);
                xx=xx->parent;
            }
            if (strcmp(sss[len-1],"\\")!=0)
                printf("%ca",gan);
            for(int i=len-1;i>=0;i--)
            {
                printf("%c",gan);
                printf("%s",sss[i]);
            }
            printf("\n");
           ///////////
        }  
        x = x->firstChild;  
        while (x != NULL)  
        {  
            QueueAppend(&Q, x);  
            x = x->nextSibling;  
        }  
    }  
    if (!ok) printf("不存在此文件或目录\n");  
    return x;  
}  

SibTreeNode **1LevelOrderTraverse(SibTreeNode *t, char a[50])  
{  
    int ok = 0;  
    SeqCQueue Q;  
    SibTreeNode *x;  
    if (t == NULL)return NULL;  
    QueueInitiate(&Q);  
    QueueAppend(&Q, t);  
    x = t->nextSibling;  
    while (x != NULL)  
    {  
        QueueAppend(&Q, x);  
        x = x->nextSibling;  
    }  
    while (QueueNotEmpty(Q))  
    {  
        QueueDelete(&Q, &x);  
        if (strcmp(x->data, a) == 0)  
        {  
            ok = 1;
            printf("查找到符合条件的有");//%s\n",x->data);
            ////////
            SibTreeNode *xx;
            xx = x;



            char sss[100][100];
            char gan = '\\';
            int len = 0;
            while (xx!=root(t) )//&& xx->parent != NULL)
            {
                strcpy(sss[len++],xx->data);
                //printf("\%s ",xx->data);
                xx=xx->parent;
            }
            if (strcmp(sss[len-1],"\\")!=0)
                printf("%ca",gan);
            for(int i=len-1;i>=0;i--)
            {
                printf("%c",gan);
                printf("%s",sss[i]);
            }
            printf("\n");
            ///////////
        }  
        x = x->firstChild;  
        while (x != NULL)  
        {  
            QueueAppend(&Q, x);  
            x = x->nextSibling;  
        }  
    }  
    if (!ok) printf("不存在此文件或目录\n");  
    return x;  
}  

//层序遍历 
SibTreeNode *LevelOrderTraverse(SibTreeNode *t, char a[50])  
{  
    SeqCQueue Q;  
    SibTreeNode *x;  
    if (t == NULL)return NULL;  
    QueueInitiate(&Q);  
    QueueAppend(&Q, t);  
    x = t->nextSibling;  
    while (x != NULL)  
    {  
        QueueAppend(&Q, x);  
        x = x->nextSibling;  
    }  
    while (QueueNotEmpty(Q))  
    {  
        QueueDelete(&Q, &x);  
        if (strcmp(x->data, a) == 0)break;  
        x = x->firstChild;  
        while (x != NULL)  
        {  
            QueueAppend(&Q, x);  
            x = x->nextSibling;  
        }  
    }  
    return x;  
}  

//查找是否存在 
int search(SibTree *t, char x[50])  
{  
    if (LevelOrderTraverse(t->root, x) == NULL)return 0;  
    else return 1;  
}  

string preorderString(SibTreeNode *currentNode, int depth)  
{  
    string s = " ";  
    stringstream out;  
    if (currentNode == NULL)  
    {  
        return "";  
    }  

    for (int i = 0; i < depth; i++)  
    {  
        s = s + " ";  
    }  
    out << currentNode->data;  
    s += out.str();  
    s += "\n";  
    s += preorderString(currentNode->firstChild, depth + 1);  
    s += preorderString(currentNode->nextSibling, depth);  
    return s;  
}  

string toString(SibTree *t)  
{  
    return preorderString(t->root, 0);  
}  
typedef  struct  
{  
    QueueDataType  queue[50];  
    int front;  
    int rear;  
    int count; /* 队列的当前表长 */  
} SeqCQueue;  

//初始化 
void QueueInitiate(SeqCQueue *Q)  
{  
    Q->front = 0;  
    Q->rear = 0;  
    Q->count = 0;  
}  

//判断队列非空 
int QueueNotEmpty(SeqCQueue Q)  
{  
    if (Q.count != 0) return 1;  
    else return 0;  
}  

//入队列 
int QueueAppend(SeqCQueue *Q, QueueDataType x)  
{  
    if (Q->count>0 && Q->rear == Q->front)  
    {  
        printf("队列已满无法插入!\n");  
        return 0;  
    }  
    else  
    {  
        Q->queue[Q->rear] = x;  
        Q->rear = (Q->rear + 1) % 50;  
        Q->count++;  
        return 1;  
    }  
}  
//出队列 
int QueueDelete(SeqCQueue *Q, QueueDataType *x)  
{  
    if (Q->count == 0)  
    {  
        printf("队列已空无数据元素出队列!\n");  
        return 0;  
    }  
    else  
    {  
        *x = Q->queue[Q->front];  
        Q->front = (Q->front + 1) % 50;  
        Q->count--;  
        return 1;  
    }  
}  
//取对头数据元素 
int QueueGet(SeqCQueue *Q, QueueDataType *x)  
{  
    if (Q->count == 0)  
    {  
        printf("队列已空无数据元素出队列!\n");  
        return 0;  
    }  
    else  
    {  
        *x = Q->queue[Q->front];  
        return 1;  
    }  
}  

测试数据:

1  
\a  
\a\aad
\a\abcde
\a\abcde\fghij
\a\abcde\fghij\aaaaabbbbb.doc
\a\aad\aa
\a\aad\aa\aaa  
\a\aad\aa\aaa\aaaaaa.doc 
0  
4  
2  
aa  
3  
aaaaaa.doc
4  
5  
aaa  
1  
asd  
4  
5  
asd  
2  
12 3  
6  
a?d  
4  
1  
\a\aad\aa\asd\aaaaabbbbb.doc
0  
4  
6  
aa*bb.doc
6  
aa*cc.doc
4  
6  
a*