使用fscanf提取双引号间字符串与数字的方法及格式符疑问
问题1:如何修改fscanf格式串提取不带引号的分区名
你当前用%s读取分区名时,会把包裹字符串的双引号一起读入,因为%s默认仅以空白字符作为分隔符,双引号不属于空白字符,会被当成普通字符读取。
修改方案很简单,用%[^"]格式符替代%s,同时显式匹配前后的双引号即可,修改后的完整格式串如下:
fscanf(fp, "%*5c%d%*c %*s %*s \"%[^\"]\"", &pnum, pname);
格式串说明:
\"显式匹配分区名前的双引号,不需要存储所以不用额外处理%[^"]读取所有不等于"的字符,直到遇到"为止,内容存入pname,自动不会包含双引号- 末尾的
\"匹配分区名后的双引号,不需要存储
问题2:为什么跳过part前缀需要%*5c而不是%*4c
%*nc的作用是严格读取n个任意字符(包括空白、特殊字符)并直接丢弃,不会自动跳过任何前缀字符。
你原本以为part只有4个字符,仅需%*4c,但实际你的输入行中part和分区编号之间还存在1个你没注意到的额外字符,大概率是空格、制表符这类不可见空白字符,也可能是部分内核版本输出的partinfo行前缀多了一个分隔字符,所以必须读满5个字符才能刚好跳过所有前缀,到达分区编号的起始位置。
如果不想硬编码字符数量,更鲁棒的写法是用%*[^0-9]替代%*5c,作用是跳过所有非数字的前缀字符,不管前缀有多长都能正常适配:
fscanf(fp, "%*[^0-9]%d%*c %*s %*s \"%[^\"]\"", &pnum, pname);
内容的提问来源于stack exchange,提问作者Zibri
相关产品推荐
相关产品推荐

