如何使用scanf从缓冲区字符串中提取符合指定格式的键值对
问题根因
你当前使用的%[a-z]=%d格式串会从输入字符串的起始位置开始匹配连续小写字母,而你的样例字符串开头是hello, ,遇到逗号时%[a-z]就匹配终止,后续=符号无法匹配到对应内容,整个sscanf匹配直接失败。
修正方案
只需要在格式串开头添加忽略规则,跳过所有非小写字母的前缀内容即可:
- 用
%*[^a-z]表示匹配所有非小写字母的字符,*修饰符表示匹配到的内容直接丢弃,不存入变量,这个写法同时兼容字符串开头就是键值对的场景,不会因为前缀为空就匹配失败 - 额外给
%[a-z]加长度限制%31[a-z],避免匹配到过长的键名时溢出你定义的32字节name缓冲区 - 增加
sscanf返回值判断,避免匹配失败时读取脏数据
修正后代码如下:
#include <stdio.h> int main() { char sentence[] = "hello, i know that rudolph=12 but it so small..."; char name[32]; int value; if (sscanf(sentence, "%*[^a-z]%31[a-z]=%d", name, &value) == 2) { printf("%s -> %d\n", name, value); } else { printf("未匹配到符合要求的键值对\n"); } getchar(); return 0; }
多键值对提取拓展
如果字符串里有多个类似key=value的结构需要批量提取,可以配合%n格式符记录每次匹配消耗的字符数,偏移字符串指针循环匹配即可:
char *p = sentence; int offset; while (sscanf(p, "%*[^a-z]%31[a-z]=%d%n", name, &value, &offset) == 2) { printf("%s -> %d\n", name, value); p += offset; // 指针偏移到本次匹配结束的位置,继续匹配下一个 }
内容的提问来源于stack exchange,提问作者bone_appettit
相关产品推荐
相关产品推荐

