2013-04-08 87 views
0

以下代码有效。sscanf指针vs变量地址

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); 

为什么?

+1

您需要让'v1'和'v2'指向有效内存。否则,你的程序有未定义的行为。 – 2013-04-08 04:18:29

回答

2

这个问题改变了!

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

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

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

更正代码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 

我觉得没有指针变量的版本是比较明智​​的。

请注意测试以确保转换工作正常!

+0

好的,但为什么我的第一个代码不会失败? – 2013-04-08 04:27:02

+0

它没有失败只是运气不好。你调用了未定义的行为。当你这样做时,任何事情都可能发生,包括灾难性的失败或行为几乎与你的预期相符。一切皆有可能。 – 2013-04-08 04:27:52