【问题标题】:Why sscanf doesn't fill the variable?为什么 sscanf 不填充变量?
【发布时间】:2012-06-13 12:42:37
【问题描述】:

我想知道为什么i 的值在sscanf 之前被调用之后是0。我期待 i 的值被修改。

我在 Windows 7 版本 3.4.4 中使用 cygwin gcc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    unsigned char a[] = {1, 2, 3, 4, 5};
    int i = 0;

    printf("\nread value %d\n", sscanf(&a, "%d", &i));
    printf("\nvalue is %d\n", i);
    printf("\nbuffer is %s\n", a);
}

输出是

读取值为0

值为0

缓冲区是一些特殊字符

【问题讨论】:

    标签: c gcc printf scanf


    【解决方案1】:

    首先,sscanf 的第一个参数应该是一个指向 char 的指针,但是你传入了一个指向 char 数组的指针,这是错误的类型。不过,这与问题无关。

    回答您的问题:sscanf(也像其他 *scanf 函数一样)仅在该值的格式说明符在字符串中匹配时才写入该值。因此,如果您有格式说明符“%d”,则仅当字符串以数字开头时,才会将 int 写入给定的 int 指针。正如您自己所说,您的字符串仅包含垃圾:值为 1 到 5 的(不可打印的)字符,后跟 a 之后内存中的任何内容。所以它不以数字开头,因此没有写数字。

    【讨论】:

    • 是的,我明白了。我想sscanf 会读取前 4 个字节(1、2、3、4),它会尝试使用 4 个字节值的组合打印一些大数字。实际上,只有当a 的每个字节包含从 48 到 57(0 到 9)的值时,它才会读取。谢谢你的解释。
    • 我对 sscanf 还有一个疑问。考虑unsigned char a[3] = 0; 缓冲区。并考虑我在前 2 个字节中查找一些有效数字。所以printf("%s", a) 正在打印一些值(75)。在这种情况下,如果我执行sscanf(&amp;a, "%d", &amp;i),该语句会尝试读取第 4 个字节,还是会在遇到\0 时自行退出第 3 个字节。
    • @rajaashok 它将读取到第一个非数字字符,在本例中为 '\0'。哦,还有:正如我之前指出的,sscanf 的第一个参数应该是 a,而不是 &amp;a
    【解决方案2】:

    sscanf 用于字符串,而不是没有终止字符 \0 的字符数组。

    http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/

    从字符串读取格式化数据从str读取数据并存储 根据参数格式进入到给定的位置 额外的论点。每个附加参数指向的位置 用它们在 格式化字符串。

    【讨论】:

      【解决方案3】:

      您的代码中没有意外行为。请注意,函数sscanf 从给定字符串中读取数据并“返回填充的变量数”。您正在传递 char 数组 a 作为从中检索数据的源,不仅它不包含任何数字(1'1' 不同)它也不是空终止的( '\0' 不见了)。

      "%d" 指定应读取十进制整数,但给定数组中没有十进制整数,因此sscanf 不读取任何数字,i 保持不变。函数返回0,表示没有填充变量。

      将您传递给sscanf 的数组的声明更改为有效字符串,它将产生所需的行为。试试char a[] = "1 2 3"

      【讨论】:

        【解决方案4】:

        这将为您提供您所期望的。

        a 已经是一个指针,所以只需 a 作为sscanf 的第一个参数就足够了。将 0(即 \0)作为 a 中的最后一个条目可能是个好主意,因为您要将它传递给 sscanfprintf,它们希望打印一个 null - 终止的字符串。

        我还将i 的类型更改为unsigned char 以匹配您正在读取的数据。

        int main()
        {
            unsigned char a[] = {1, 2, 3, 4, 5, 0};
            unsigned char i = 0;
        
            printf("\nread value %d\n", sscanf(a, "%c", &i));
            printf("\nvalue of i is %d\n", i);
            printf("\nbuffer is %s\n", a);
            return 0;
        }
        

        注意:您之前得到 0 是因为 sscanf 未能从 a 为您“读取”任何数据。

        【讨论】:

          猜你喜欢
          • 2017-05-23
          • 2010-12-20
          • 1970-01-01
          • 2023-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多