swscanf_s在读入wchar_t数组时会导致错误

时间:2014-05-18 14:23:21

标签: c++ string

我正在使用格式L"79349 Dexter 03 05"

编写一个简单的序列化

(假设Dexter部分总是1个字。)

此字符串将被读入3个intwchar_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&#39; 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);

我做错了什么?

我的猜测是,我遗漏了一些简单而微不足道的东西,但却找不到我自己的东西。提前谢谢。

1 个答案:

答案 0 :(得分:2)

目前我的声誉太少,无法发表评论。正如Brett所说,你需要使用wcstok_s。你要做的是将长字符串“标记”为较小的标记字符串。这就是wcstok_s将为您做的事情。另一方面,swscanf_s将尝试将您传递的整个字符串转换为第一个格式参数。

这对您不起作用的另一个原因是您没有指定要扫描的字节数。 “_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将原始字符串拆分为更小的子字符串(标记),那么你需要将你知道的字符串转换为整数。

通常,您可以搜索“C ++ tokenize”,您应该找到很多示例。