linux的特色:
- 路径使用 / 字符来分割各单元,
- 使用 … 来代表上级目录,
- 使用 . 来代表本级目录,
- 如果是 / 开头就是绝对路径,否则是相对路径。
整套体系都非常完美的解决了文件的索引问题,之前就有对 linux 路径进行分析想法,这里总算折腾出一个有效的分析方法。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
const char *path = "//../.././../../1abc/2abc///2.1abc/3abc/4abc/../../5abc/6abc/../7abc/8abc/9abc/.";
typedef struct str_split_{
const char **point;
int *slen;
int num;
} str_split_t;
int str_split(const char *str, char split, str_split_t * spl_str)
{
const char *t = str;
int count = 1;
// 第一次循环,查看字符串的信息
while (*t != 0){
if (*t == split){
count++;
}
t++;
}
// 根据字符串信息分配存储空间
spl_str->num = count;
spl_str->point = (const char **)malloc(count * sizeof(char *));
spl_str->slen = (int *)malloc(count * sizeof(int));
*(spl_str->point) = str;
count = 0;
int slen = 0;
t = str;
// 第二次循环,统计字符串信息
while (1){
if (*t == split){
*((spl_str->point) + count + 1) = t + 1; //记下字符串的开头
*(spl_str->slen + count) = slen; // 记下上一个字符串的长度
slen = 0;
count++;
}else if (*t == 0){
*(spl_str->slen + count) = slen;
break;
}else{
slen++;
}
t++;
}
return 0;
}
// 释放分割的信息内存
int free_split_info(str_split_t *spl_str){
if (spl_str== NULL){
return EINVAL;
}
free(spl_str->point);
free(spl_str->slen);
}
int get_path_info(const char *path)
{
str_split_t spl_str={0};
int temp = str_split(path,'/', &spl_str);
char deal_path[256]={0};
// 获取有效的路径位置
char *is_valid_name = (char *)malloc(spl_str.num * sizeof(char)); // {0};
memset(is_valid_name,0,spl_str.num * sizeof(char));
int valid_name_i = 0;
for (int i = 0; i < spl_str.num; i++){
if (spl_str.slen[i] == 0){
continue;
}else if (spl_str.slen[i] == 2 && strncmp(spl_str.point[i],"..",2) == 0 ){ // 返回上级目录
while (valid_name_i != 0){
if (is_valid_name[valid_name_i]){
is_valid_name[valid_name_i] = 0;
break;
}
valid_name_i--;
}
continue;
}else if (spl_str.slen[i] == 1 &&strncmp(spl_str.point[i],".",1) == 0){
continue;
}else{
is_valid_name[i] = 1;
valid_name_i = i;
}
}
// 打印路径信息
for (int i = 0; i < spl_str.num; i++){
printf("%d, ", is_valid_name[i]);
for (int j = 0; j < spl_str.slen[i]; j++)
{
printf("%c", spl_str.point[i][j]);
}
printf("\n");
}
// 将有效位置整理成字符串
for (int i = 0; i < spl_str.num; i++){
if (!is_valid_name[i]){
continue;
}
if (deal_path[0] != 0){
strcat(deal_path, "_");
}
strncat(deal_path, spl_str.point[i], spl_str.slen[i]);
}
free_split_info(&spl_str);
free(is_valid_name);
return 0;
}
int main(){
get_path_info(path);
return 0;
}
操作系统是一个国痛,文件系统是操作系统的重要部分,上面代码有基础的注释,供大家参考。