You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何从块设备路径中分离提取分区号与设备名称

问题说明
  • 待处理的存储设备路径为字符数组格式,示例:char str[20]="/dev/sda1"
  • 提取目标:
    • 分区号:示例提取结果为1
    • 块设备名称:示例提取结果为sda1
  • 原有问题写法:sscanf(str,"%[^0123456789]", temp); 仅能存入路径中的非数字前缀,无法同时获取分区号和完整块设备名。
实现方案

原有写法的问题在于%[^0123456789]格式符会在匹配到第一个数字时直接终止读取,自然拿不到数字部分的分区号,也拿不到完整的块设备名。根据场景不同可以选两种实现方式:

通用兼容方案(推荐)

兼容SATA(sdaX)、NVMe(nvme0n1pX)、emmc(mmcblk0pX)等所有常见Linux存储设备路径格式,逻辑分两步:

  1. 跳过固定路径前缀/dev/,提取后续全部字符串作为块设备名称
  2. 从块设备名称末尾向前遍历,找到连续数字段的起始位置,转换为整数即为分区号

示例代码:

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:18:21