【问题标题】:sscanf pointer vs variable addresssscanf 指针与变量地址
【发布时间】:2013-04-08 04:14:38
【问题描述】:

以下代码有效。

unsigned int i1;unsigned int i2;
float *v1;float *v2;
sscanf("1 1 2.0 3.0","%u %u %f",&i1,&i2,v1,v2);
printf("%f",v1);

再添加一个 %f,下面的不行。它编译但我得到 bash: [9612: 1 (255)] tcsetattr: 设备的 ioctl 不合适。

unsigned int i1;unsigned int i2;
float *v1;float *v2;
sscanf("1 1 2.0 3.0","%u %u %f %f",&i1,&i2,v1,v2);

为什么?!

【问题讨论】:

  • 你需要让v1v2指向有效内存。否则,您的程序会有未定义的行为。

标签: c pointers scanf


【解决方案1】:

问题变了!

您的第一个代码应该失败;你需要传递&v1 并且传递v2 是没有意义的,因为它(a)不是地址并且(b)无论如何都没有转换规范。

第一个代码应该会失败,因为您没有在v1 中传递一个初始化的指针,并且传递v2 没有意义,因为它既没有被初始化也没有被格式字符串使用。当您将未初始化的指针传递给sscanf() 时,您会调用未定义的行为,并且任何响应都是可接受的——灾难性故障(擦除磁盘?),或几乎与预期一样的良性行为(即使没有充分的理由期待这种良性行为) )。类似的 cmets 适用于大多数功能;不要传递未初始化的指针;这样做很少有什么好处。

第二个失败,因为您没有传递初始化地址。

更正代码 1:

unsigned int i1;
unsigned int i2;
float f1;
float *v1 = &f1;
if (sscanf("1 1 2.0 3.0", "%u %u %f", &i1, &i2, v1) == 3)
    printf("%f\n", *v1);

(已删除未使用的变量v2。)

备选方案 1:

unsigned int i1;
unsigned int i2;
float v1;
if (sscanf("1 1 2.0 3.0", "%u %u %f", &i1, &i2, &v1) == 3)
    printf("%f\n", v1);

(无指针变量。)

更正代码 2:

unsigned int i1;
unsigned int i2;
float v1;  // Not pointer
float v2;  // Not pointer
if (sscanf("1 1 2.0 3.0", "%u %u %f %f", &i1, &i2, &v1, &v2) == 4)
    printf("%f %f\n", v1, v2);

或者:

unsigned int i1;
unsigned int i2;
float f1;
float f2;
float *v1 = &v1;  // Initialized pointer
float *v2 = &v2;  // Initialized pointer
if (sscanf("1 1 2.0 3.0", "%u %u %f %f", &i1, &i2, v1, v2) == 4)
    printf("%f %f\n", f1, f2);  // Or *v1, *v2

我认为没有指针变量的版本更明智。

注意测试以确保转换成功!

【讨论】:

  • 没有失败只是运气不好。您调用了未定义的行为。当您这样做时,任何事情都可能发生,包括灾难性故障或几乎符合您预期的行为。一切皆有可能。
猜你喜欢
  • 1970-01-01
  • 2020-12-30
  • 2016-08-25
  • 1970-01-01
  • 1970-01-01
  • 2021-04-01
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多