C - sscanf 未提取模式



我试图找出我应该给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_sizeunit这就解释了为什么memory_sizeunit不变。您需要的是格式字符串

sscanf(list, "%*[^(](%d%2[^)]%*s", &memory_size, unit);

在这里,在格式字符串中"%*[^(](%d%2[^)]%*s" -

  1. %*[^(]意味着sscanf将首先读取并丢弃不包含字符(的字符序列。
  2. (意味着sscanf将读取和丢弃(
  3. %d表示sscanf将读取十进制整数。
  4. %2[^)]意味着sscanf最多读取不包含)2字符序列,并将它们存储在相应的参数中。这是为了确保sscanf不会在要存储的字符串太大的情况下溢出缓冲区unit。它比 unit 的大小小 1,以节省终止空字节的空间,该空字节由缓冲区末尾的 sscanf 自动添加。
  5. %*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"

相关内容

  • 没有找到相关文章

最新更新