我正在使用L"79349 Dexter 03 05"
格式编写一个简单的序列化
(假设Dexter
部分始终为1个字。)
该字符串将被读入3个int
和一个wchar_t
数组
我目前有以下代码:
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main()
{
int id=-1,season=-1,episode=-1;
wchar_t name[128];
swscanf_s(L"79349 Dexter 03 05", L"%d %ls %d %d", &id, name, &season, &episode);
wcout << "id is " << id << endl;
wcout << "name is " << wstring(name) << endl; //wprintf(L"name is %ls",name);
wcout << "season is " << season << endl;
wcout << "episode is " << episode << endl;
}
上面的代码已编译(在VS '13中),没有问题,但是在执行时会崩溃。使用调试选项,我收到消息:
Unhandled exception at 0xFEFEFEFE in test3.exe: 0xC0000005: Access violation executing location 0xFEFEFEFE.
通过省略某些部分,我发现在阅读
name
时会发生此问题。例如,以下工作正常:
swscanf_s(L"79349 Dexter 03 05", L"%d %*ls %d %d", &id, &season, &episode);
我究竟做错了什么?
我的猜测是我缺少一些简单而琐碎的东西,但我自己却找不到。提前致谢。
最佳答案
我的声誉目前很少有人评论。正如Brett所说,您需要使用wcstok_s。您想要做的是将长字符串“标记”为较小的标记字符串。这就是wcstok_s会为您做的。另一方面,swscanf_s将尝试将您传递的整个字符串转换为第一个format参数。
这对您不起作用的另一个原因是,您尚未指定要扫描的字节数。 “_s”版本更“安全”,因为它们可以防止缓冲区溢出,这会损坏内存并引起各种问题。如果您更换:
swscanf_s(L".IHATECPP.",L".%ls.",name);
与
swscanf_s(L".IHATECPP.", L".%ls.", name, _countof(name));
结果将是:
IHATECPP.
。首先 ”。” (点)未解析。这个问题:如果可以使用更多的C++风格的例程而不是较早的C风格的例程,Split a string in C++?可能会对您有所帮助。如果您由于某种原因而无法这样做,那么:C++ Split Wide Char String可能会为您提供一些想法,因为它使用的是wcstok()。一旦wcstok_s将原始字符串拆分为较小的子字符串( token ),则需要将已知的字符串转换为整数。
通常,您可以搜索“C++标记化”,并且应该找到很多示例。