You need to enable JavaScript to run this app. C语言中sscanf解析字符串异常,全量内容存入user变量的问题
优惠活动
大模型
产品
解决方案
定价
更多

C语言中sscanf解析字符串异常,全量内容存入user变量的问题

问题本质

解析异常完全来自sscanf对%s格式符的固定匹配规则,和格式串的预期逻辑存在偏差:

  • %s的匹配逻辑是:跳过前导空白后,连续读取所有非空白字符,直到碰到第一个空白字符、或者达到指定的读取长度上限才停止。
  • 写在%s后面的@并不是%s的终止匹配符,它是%s完成读取动作之后,才会去匹配的固定常量字符。
匹配流程还原

拿测试字符串"johnsmith@yahoo.com, 22:44:45"走一遍解析流程就能明确问题:

  1. 第一个转换符是%44s,从字符串起始位置开始扫描:整段从开头到逗号的内容johnsmith@yahoo.com, 里没有任何空白字符,完全满足%s的匹配要求,加上总长度远小于44的上限,所以这段内容会被全部写入user数组。
  2. 读取完成后,sscanf的内部读写指针已经移动到了逗号后面的空格位置,跳过空白后停在时间部分的开头22处。
  3. 按照格式串,接下来需要匹配固定字符@,但当前位置的字符是数字2,和@完全不匹配,整个解析流程直接终止。
  4. 因为解析提前中断,email、h、m、s几个变量完全没有被写入有效值,保留了栈上未初始化的随机垃圾值,和实际看到的输出表现完全一致。
修复方案

如果要让内容读取到指定字符(比如碰到@、碰到逗号就停止)就终止读取,不能用默认的%s,需要使用扫描集语法重写格式串:

sscanf(str, "%44[^@]@%44[^,], %d:%d:%d", user, email, &h, &m, &s);

对应格式符的含义:

  • %44[^@]:最多读取44个字符,碰到@就立刻停止,不会把@本身纳入读取内容,刚好匹配@前面的用户名部分
  • @:匹配字符串里的@分隔符,不会写入任何变量
  • %44[^,]:最多读取44个字符,碰到逗号就立刻停止,刚好匹配@后面、逗号前面的邮箱域名部分
  • 后续的, %d:%d:%d匹配逗号、空格和三段时间数值,完成完整解析

补充提示:使用sscanf时一定要检查返回值,返回值代表成功完成转换并写入的变量数量,原代码的返回值会是1,代表只有第一个变量被成功写入,后续解析全部失败,这个检查可以帮你快速定位这类格式匹配问题。

内容的提问来源于stack exchange,提问作者Andrei0408

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 00:15:05