C语言如何从块设备路径中分离提取分区号与设备名称
问题说明
- 待处理的存储设备路径为字符数组格式,示例:
char str[20]="/dev/sda1" - 提取目标:
- 分区号:示例提取结果为
1 - 块设备名称:示例提取结果为
sda1
- 分区号:示例提取结果为
- 原有问题写法:
sscanf(str,"%[^0123456789]", temp);仅能存入路径中的非数字前缀,无法同时获取分区号和完整块设备名。
实现方案
原有写法的问题在于%[^0123456789]格式符会在匹配到第一个数字时直接终止读取,自然拿不到数字部分的分区号,也拿不到完整的块设备名。根据场景不同可以选两种实现方式:
通用兼容方案(推荐)
兼容SATA(sdaX)、NVMe(nvme0n1pX)、emmc(mmcblk0pX)等所有常见Linux存储设备路径格式,逻辑分两步:
- 跳过固定路径前缀
/dev/,提取后续全部字符串作为块设备名称 - 从块设备名称末尾向前遍历,找到连续数字段的起始位置,转换为整数即为分区号
示例代码:
#include <stdio.h> #include <string.h> #include <ctype.h> int main() { char dev_path[20] = "/dev/sda1"; char block_name[20] = {0}; int part_num = 0; // 提取/dev/后的完整块设备名 if (sscanf(dev_path, "/dev/%s", block_name) != 1) { printf("设备路径格式非法\n"); return -1; } // 从末尾向前查找分区号起始位置 int name_len = strlen(block_name); int cursor = name_len - 1; while (cursor >= 0 && isdigit(block_name[cursor])) { cursor--; } // 末尾无数字代表是整盘设备,无分区号 if (cursor == name_len - 1) { printf("块设备名:%s,无分区号\n", block_name); return 0; } // 转换分区号为整数 sscanf(block_name + cursor + 1, "%d", &part_num); printf("提取结果:\n块设备名称:%s\n分区号:%d\n", block_name, part_num); return 0; }
运行输出:
提取结果: 块设备名称:sda1 分区号:1
简易快速方案(仅适配传统SATA/IDE设备)
如果业务场景只会用到sda1、hdb2这类设备名本身不含数字的传统存储设备,可以直接用sscanf一次性匹配前缀和分区号,再拼接成完整块设备名,代码更短:
char dev_path[20] = "/dev/sda1"; char name_prefix[16] = {0}; int part_num = 0; char block_name[20] = {0}; sscanf(dev_path, "/dev/%[^0-9]%d", name_prefix, &part_num); sprintf(block_name, "%s%d", name_prefix, part_num);
注意:该方案无法正确识别nvme0n1p2这类名称内嵌数字的设备,会将第一个出现的数字误判为分区号,无特殊兼容需求优先选第一种通用方案。
内容的提问来源于stack exchange,提问作者sanvi
相关产品推荐
相关产品推荐

