You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

swscanf未解析至$符号,无法移除字符串中的$符号问题

解决swscanf无法截断$符号的问题

哦这个问题我熟!你现在的问题出在对swscanf格式字符串的理解上,咱们一步步来捋清楚:

为什么原来的代码不起作用?

你写的格式串L"%ls$"逻辑有问题:

  • %ls是宽字符版本的字符串读取格式,它会读取所有连续的非空白宽字符——这意味着它会把输入字符串L".exe$"里的.exe$全部读进name数组,因为$不属于空白字符。
  • 格式串末尾的$是字面匹配要求:它期望读完%ls之后,输入指针的下一个字符是$,但这时候输入已经被%ls读完了,没有剩余字符可以匹配。不过swscanf不会回溯已经读取的内容,所以name里还是保留了完整的.exe$。

正确的解决方案

要实现"读取到$就停止"的需求,最精准的方法是使用扫描集格式符%[^$],这个格式符的含义是:读取所有**不是$**的宽字符,直到遇到$或者输入结束为止。

修正后的代码

#include <iostream>
#include <string>

int main() {
    wchar_t name[10];
    // 用扫描集读取到$为止,同时指定宽度9防止缓冲区溢出(留1位存终止符)
    swscanf(L".exe$", L"%9[^$]", name);
    std::wcout << std::wstring(name) << std::endl;
    return 0;
}

关键细节说明

  • 扫描集%[^$]会自动在读取的字符串末尾添加宽字符终止符\0,不用担心字符串不完整的问题。
  • 加上9(即%9[^$])是为了防止输入过长时缓冲区溢出——因为name数组只有10个wchar_t元素,必须留一个位置给终止符。

其他可选方案

如果你明确知道需要读取的字符长度(比如这里是3个字符.exe),也可以直接指定读取宽度:

swscanf(L".exe$", L"%3ls", name);

不过这种方法不够灵活,如果输入字符串长度变化(比如.dll$),就需要修改格式串,而扫描集方法可以自适应任意长度的前缀直到$出现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:56:21