【问题标题】:Getting error with sscanf_s in Visual Studio 2012在 Visual Studio 2012 中出现 sscanf_s 错误
【发布时间】:2015-07-24 06:36:28
【问题描述】:

我正在尝试解析以下字符串-"DATA,97,103,100,97,84,69"。该字符串可以有以下变体-

"DATA,100,10,1,9,82,60"
"DATA,57,27,59,30,11,64"
"DATA,12,86,100,97,103,23"
"DATA,1,10,78,38,45,52"
"DATA,99,43,85,28,84,26"

请注意,第一个 "DATA," 永远不会改变。其余整数从 0 到 200 不等。下面是使用 sscanf_s 函数解析这些字符串的代码-

char ignore_data[5];
int x1,x2,x3,y1,y2,y3;
char str[]="DATA,97,103,100,97,84,69";

sscanf_s(str,"%5[^,],%d,%d,%d,%d,%d,%d", ignore_data, &x1, &x2, &x3, &y1, &y2, &y3);
printf("str=%s, x1=%d, x2=%d, x3=%d, x1=%d, y2=%d, y3=%d",str, x1, x2, x3, y1, y2,y3);

代码不起作用并显示以下错误

My Application.exe 中 0x510A06E4 (msvcr110d.dll) 处的未处理异常:0xC0000005:访问冲突写入位置 0x00870000。

当sscanf() 与#define _CRT_SECURE_NO_WARNINGS 预处理器一起使用时,上述代码完美运行。

我想获取x1、x2、x3、y1、y2 和 y3 的值。我在这里错过了什么?

【问题讨论】:

    标签: c visual-studio-2012 input scanf


    【解决方案1】:

    我发现如果你能够实现以下你应该能够得到你需要的结果:

    #include <stdio.h>
    
    int main()
    {
        char ignore_data[5];
        int x1, x2, x3, y1, y2, y3;
        char str[] = "DATA,97,103,100,97,84,69";
    
        sscanf_s(str, "%5[^,],%d,%d,%d,%d,%d,%d", ignore_data, sizeof(ignore_data), &x1, &x2, &x3, &y1, &y2, &y3);
        printf("str=%s, x1=%d, x2=%d, x3=%d, x1=%d, y2=%d, y3=%d", str, x1, x2, x3, y1, y2, y3);
    
        return 0;
    }
    

    对于sscanf_s,在接收字符串时,在扫描数据后,您将需要目标缓冲区的大小。这有助于在输入流(无论它可能是什么)与目标之间建立一个安全端口,从而减少接受字符串时缓冲区溢出的可能性。

    编辑:

    正如 Cremno 指出的那样,它需要是 sscanf_s(str, "%5[^,],%d,%d,%d,%d,%d,%d", ignore_data, (unsigned)sizeof(ignore_data), &amp;x1, &amp;x2, &amp;x3, &amp;y1, &amp;y2, &amp;y3);

    注意sizeof(ignore data) 应该返回一个无符号值。

    【讨论】:

    • 必须是(unsigned)sizeof(ignore_data)。请参阅文档。
    • @Kozmik:我还没有测试你的代码。非常感谢您的建议。好吧,我不想要ignore_data,我只想要x1、x2、x3、y1、y2 和y3。你能告诉我如何摆脱ignore_data变量吗?
    • @RaviJoshi - 你的意思是根本不从str 阅读它? sscanf_s(str, "%*[^,],%d,%d,%d,%d,%d,%d", &amp;x1, &amp;x2, &amp;x3, &amp;y1, &amp;y2, &amp;y3); - 在第一个 , 之前不会读取前几个字符。让我知道这是否有帮助。
    【解决方案2】:

    引用C11 标准,附录 K,第 §K.3.5.3.2 章,fscanf_s() 函数,(强调我的)

    fscanf_s() 函数等效于 fscanf() 除了 c、s 和 [ 转换说明符适用于一对参数(除非分配抑制由 *)。这些参数中的第一个与fscanf() 相同。该参数在参数列表中紧跟第二个参数,其类型为rsize_t,并给出数组中由该对的第一个参数指向的元素的数量。 [...]

    现在,进入sscanf_s() 的范围,第 §K.3.5.3.7 章

    sscanf_s 函数等效于fscanf_s,除了输入是从字符串(由参数s 指定)而不是从流中获取的。 [...]

    希望以上文本足以指出错误,您缺少[ 所需的第二个参数,该参数出现在格式字符串中。您需要提供ignore_data 的大小,如rsize_t 类型。

    【讨论】:

    • 问题是关于微软的sscanf_s()。 C11 无关紧要。然而这是同一个问题,只是unsigned 而不是rsize_t。
    • @cremno 自从“微软”开始编写语言以来?这是他们的实施。所以,C11 是相关的。如果有些东西不符合标准,那不是标准的问题,主要是糟糕的实现问题。
    • 不,C11 无关紧要,因为十年前微软发明并实施他们的sscanf_s() 时它并不存在。
    • SouravGhosh 和@cremno:非常感谢你们的帮助。我相信Kozmik's solution 应该可以正常工作(虽然我还没有测试过)。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 2015-03-24
    相关资源
    最近更新 更多