我的字符串可能有也可能没有参数,所以我想把这种灵活性插入到我的sscanf中。
例如我的字符串可以是" 111 | g | 8 | 9 | r | 4 | 5" ,其中第3和第4是可选参数,所以我们可以有一个输入如下" 111 | g ||| r | 4 | 5"
在正则表达式中是否有类似*的通配符,我可以使用吗?
例如sscanf(mystr,"%d|%c|*|*|%c|%d|%d", &int1, &char1, &int2, &int3, &char2,&int4,&int5);
答案 0 :(得分:2)
不,你不能。
scanf
只能进行简单转换。如果您需要更复杂的匹配,则必须构建自定义解析器或使用更丰富的库。
这里,解析可以手工完成:
'|'
=>搜索字符串中的下一个strchr
如果没有找到,你有最后一个令牌'|'
替换为'\0'
答案 1 :(得分:1)
我认为你不能选择scanf,所以我建议你使用fgets然后对返回的数据进行排序。
答案 2 :(得分:1)
不,不是你想要使用它的方式。但是,还有其他选择。
正如其他人所说,您可以使用strsep()
来分隔输入。
以下代码允许任何字段为空,实质上,它更像是格式代码或通配符(在正则表达式中解释为\d|*\|\w|*\|\d|*\|\d|*\|\w|*\|\d|*\|\d|*
)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *my_string;
my_string = malloc(sizeof(char)*256);
char *my_string_split;
printf("Input: ");
fgets(my_string, 256, stdin);
char char1;
char char2;
int int1;
int int2;
int int3;
int int4;
int int5;
my_string_split = strsep(&my_string, "|");
for (int i = 0; my_string_split != NULL; i++) {
switch (i) {
case 0:
sscanf(my_string_split, "%d", &int1);
break;
case 1:
sscanf(my_string_split, "%c", &char1);
break;
case 2:
sscanf(my_string_split, "%d", &int2);
break;
case 3:
sscanf(my_string_split, "%d", &int3);
break;
case 4:
sscanf(my_string_split, "%c", &char2);
break;
case 5:
sscanf(my_string_split, "%d", &int4);
break;
case 6:
sscanf(my_string_split, "%d", &int5);
break;
}
my_string_split = strsep(&my_string, "|");
}
printf("%d|%c|%d|%d|%c|%d|%d", int1, char1, int2, int3, char2, int4, int5);
free(my_string);
return 0;
}
正常输入
Input: 111|g|8|9|r|4|5
111|g|8|9|r|4|5
使用空字段处理输入
Input: 111|g|||r|4|5
111|g|0|0|r|4|5
此外,如果您的系统未提供strsep()
,则还有另一个stackoverflow问题,该问题有解决方法:https://stackoverflow.com/a/8514474/6051408