像树命令一样的打印线

时间:2016-10-02 07:24:18

标签: c linux

我正在尝试为工作中的任务学习C编程,我为自己设置了一个小项目,其中包括读取包含所有子目录的文件树,以获取有关每个文件的信息。

我无法解决的问题是如何在打印所有目录时按照真实树命令进行操作。

这是我的示例代码:

Sub test()
Dim z As String
For z = 14 To 17
For b = 14 To 17

ActiveSheet.Cells(b, 13) = "z"

Next z
Next b

End Sub
请给我一些想法!

2 个答案:

答案 0 :(得分:0)

list(buf,indentlevel+4);

您应该将其更改为list(buf,indentlevel+1),因为您只升级到一个级别。这样您就可以跟踪目录级别。添加另一个函数来添加额外的空格。请参阅以下示例:

void space(int level, int file)
{
    int i;
    for (i = 0; i < level + 1; i++)
        printf("\x0b3   "); // add the '│' character
    if (file) 
        printf("\x0c3\x0c4  "); // add  '├' and '─' characters
}

void list(const char *path, int indentlevel)
{
    DIR *dirp = opendir(path);
    struct dirent *dentry;
    char buf[1024];
    if (!dirp)
    {
        printf("%*sNo access\n",indentlevel,"");
        return;
    }

    int i;
    while ((dentry = readdir(dirp)) != NULL)
    {
        sprintf(buf,"%s/%s", path, dentry->d_name);
        switch (testDir(buf,dentry->d_name))
        {
        case doSkip:
            break;
        case isDir:
            space(indentlevel, 1);
            putchar('\n');
            space(indentlevel, 0);
            printf("[ %s ]\n",dentry->d_name);
            list(buf,indentlevel+1);
            break;

        case isFile:
            space(indentlevel-1, 1);
            printf("%s\n",dentry->d_name);
            break;
        }
    }

    closedir(dirp);
}

这是一个更复杂的版本,它将数据存储在缓冲区中,因此它可以找到文件夹中的最后一个子项,并为最后一项绘制正确的“方边”字符。它仍会打印一些额外的垂直线,需要注意。

//store directory information
typedef struct TT_dir
{
    char* name;
    int isdir;
    int level;
    int islast;
} T_dir;

//vector for holding lines of data
typedef struct TT_vector
{
    T_dir *data;
    int capacity;
    int size;
} T_vector;

void vector_add(T_vector *pvec, char *buf, int isdir, int level)
{
    if (pvec->size == pvec->capacity)
    {
        pvec->capacity += 16;
        pvec->data = realloc(pvec->data, pvec->capacity * sizeof(T_dir));
    }

    char *duplicate = malloc(strlen(buf) + 1);
    strcpy(duplicate, buf);
    pvec->data[pvec->size].name = duplicate;
    pvec->data[pvec->size].isdir = isdir;
    pvec->data[pvec->size].level = level;
    pvec->data[pvec->size].islast = 0;
    pvec->size++;
}

void list(const char *path, int level, T_vector *pvec)
{
    DIR *dirp = opendir(path);
    struct dirent *dentry;
    char buf[4096];
    if (!dirp)
    {
        printf("%*sNo access\n", level, "");
        return;
    }

    int haschildren = 0;
    while ((dentry = readdir(dirp)) != NULL)
    {
        sprintf(buf, "%s/%s", path, dentry->d_name);
        switch (testDir(buf, dentry->d_name))
        {
        case doSkip:
            break;
        case isDir:
            //show progress:
            printf(".");

            //add directory info to vector array
            vector_add(pvec, dentry->d_name, 1, level);

            //next dir...
            list(buf, level + 1, pvec);
            haschildren = 1;
            break;

        case isFile:
            //add directory info to vector array
            vector_add(pvec, dentry->d_name, 0, level);
            haschildren = 1;
            break;
        }
    }

    //needs this information for drawing the correct character
    if (haschildren)
        pvec->data[pvec->size - 1].islast = 1;

    closedir(dirp);
}

int main()
{
    T_vector vec;
    vec.capacity = 0;
    vec.size = 0;
    vec.data = 0;

    list(".", 0, &vec);
    printf("\n");

    int i, k;
    for (i = 0; i < vec.size; i++)
    {
        if (vec.data[i].isdir)
        {
            for (k = 0; k < vec.data[i].level; k++) printf("\x0b3   ");
            printf("\x0b3\n");

            for (k = 0; k < vec.data[i].level; k++) printf("\x0b3   ");

            printf(vec.data[i].islast ? "\x0c0" : "\x0c3");

            printf("\x0c4  %s:\n", vec.data[i].name);
        }
        else
        {
            for (k = 0; k < vec.data[i].level; k++) printf("\x0b3   ");

            printf(vec.data[i].islast ? "\x0c0" : "\x0c3");

            printf("\x0c4  %s\n", vec.data[i].name);
        }
    }

    return 0;
}

答案 1 :(得分:-1)

您需要的洞察力是printf不必打印整行。与其他语言中的其他打印功能不同。

for(i=0;i<identlevel;i++)
  printf("-");
 printf("[ %s ]\n", dentry->dname);

会做的伎俩。