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
相关产品推荐
相关产品推荐

