我试图找出我应该给sscanf的模式。我有一个字符串 abcde(1GB(。我想提取 1 和 GB。我正在使用
char list[]= "abcde(1GB)";
int memory_size =0;
char unit[3]={0} ;
sscanf(list, "%*s%d%s" , &memory_size, unit);
我在打印时没有看到提取的令牌,我看到单位为 memory_size =0 和 NULL。
谢谢
您的sscanf()
字符串格式应为:
sscanf(list, "%*[^(](%d%[^)]" , &memory_size, unit);
-
%[^)]
表示捕获字符并在查找字符串)
或结尾时停止缓存 -
%*[^(]
表示:-
[^(]
意味着在查找字符时捕获字符并停止缓存(
- 而不是更传统的%s
- 捕获字符并在查找空格字符时停止缓存"> -
*
的意思是"读取但不存储">
-
格式字符串中的%s
转换说明符 scanf
表示scanf
将读取一系列非空格字符。%*s
中的*
称为赋值抑制字符。这意味着scanf
将读取和丢弃非空格字符。
由于%s
匹配任何非空格字符序列,因此%*s
in "%*s%d%s"
表示sscanf
将读取丢弃字符串list
中的所有字符。因此,数组中没有任何剩余list
可以读取并分配给参数&memory_size
和unit
。这就解释了为什么memory_size
和unit
不变。您需要的是格式字符串
sscanf(list, "%*[^(](%d%2[^)]%*s", &memory_size, unit);
在这里,在格式字符串中"%*[^(](%d%2[^)]%*s"
-
-
%*[^(]
意味着sscanf
将首先读取并丢弃不包含字符(
的字符序列。 -
(
意味着sscanf
将读取和丢弃(
。 -
%d
表示sscanf
将读取十进制整数。 -
%2[^)]
意味着sscanf
最多读取不包含)
的2
字符序列,并将它们存储在相应的参数中。这是为了确保sscanf
不会在要存储的字符串太大的情况下溢出缓冲区unit
。它比unit
的大小小 1,以节省终止空字节的空间,该空字节由缓冲区末尾的sscanf
自动添加。 -
%*s
表示sscanf
将读取和丢弃任何剩余的非空格字符序列。
请通过以下链接获取sscanf((函数。
斯坎夫功能说明
现在
根据穆罕默德所说%[^(]
是为了抓住角色直到"("
表示%*[^(]
将字符串截断,直到%d
之后(
为整数数据,然后捕获字符串直到)
。
接受答案后 - 补充
@MOHAMED答案很好,但以下是候选人的改进。
1( 始终检查sscanf()
结果以确保按预期扫描数据。
if (sscanf(list, "%*[^(](%d%[^)]", &memory_size, unit) != 2) ScanFailure();
2( 使用"%s"
或"%[]"
说明符时,请包括限制长度。@ajay
char unit[3]={0} ;
// v--- 1 less than buffer size.
if (sscanf(list, "%*[^(](%d%2[^)]" , &memory_size, unit) != 2) ScanFailure();
3(附加"%n"
(保存扫描位置(是检测尾随)
的可靠方法,并且输入字符串的末尾没有额外的垃圾。
"%n"
不会增加sscaanf()
结果。
int n = 0;
// )%n <--- Look for ) then save scan position
if (sscanf(list, "%*[^(](%d%2[^)])%n", &memory_size, unit, &n) != 2) ||
list[n] != ' ') ScanFailure();
4(为可选的空白空间可能/可能没有用。说明符已允许可选的前导空格。 3 例外:%c %[] %n
"%*[^(](%d%2[^)])%n"
// v v v
" %*[^(](%d %2[^)]) %n"