2013-04-08 114 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