2017-06-04 68 views
1

我想檢查我的輸入是否是整數(例如,不是字符或字符串)。檢查C中的輸入類型

#include <stdio.h> 

int main (void) 
{ 
    float a; 
    int q; 

    printf("\nInsert number\t"); 
    scanf("%f",&a); 

    q=(int)a; 
    ++q; 

    if((q - a) != 1) 
     printf("\nThe number is not an integer\n\n"); 
    else 
     printf("\nThe number is an integer\n\n"); 

    return 0; 
} 

是否有人可以解釋爲什麼它的工作原理: 我碰到這個代碼(即作品)偶然?

+3

該代碼是不可能的,如果你輸入987654321作爲價值的工作。如果您輸入ABC,則更不可能工作。 –

+0

這段代碼與輸入是「char」還是「string」無關。 –

+1

*總是*測試'scanf'的返回值,這裏應該是'1'。如果你想輸入一個'int',那麼這樣做,檢查1值是否被轉換,並檢查輸入流中的下一個「char」是否爲空格。 –

回答

1

本身是相當簡單的,我們正在改變鑄造floatint然後該代碼遞增int值:

q=(int)a; 
++q; 

然後,每次有作爲輸入提供的int,的(q-a)結果將是正好是1。但是,它提供的輸入(並保存到float a)類型爲float,結果將大於1(對於正數)。

這是因爲在(q-a),q將被轉換爲float,其結果也將是float

參見例如用於the C book

否則,如果操作數是浮點數,則另一個是 轉化爲浮動,那就是結果的類型。

+2

[如果要轉換的值超出可以表示的值的範圍,則行爲未定義。](http://port70.net/~nsz/c/c11/n1570.html#6.3.1.4p2)它'float's可以保存不能用int表示的值。 –

+0

我不建議在任何地方使用此代碼,問題是它是如何工作的,只是解釋它。 – syntagma

+0

同意不推薦。只是認爲UB是這個代碼的一個重要特徵(同樣,如果用戶輸入了UB,例如一個字符串),因此評論。 –

1

你把輸入a這是一個浮點數。然後,您將float轉換爲int整數q和增量1 (q++)。所以,如果你需要輸入a = 3.4

q=(int)a; ++q;

然後q將是4。但它不能改變a的值。所以a將是3.4。 檢查此條件後(q - a) != 1將爲true,否則爲false。

最後,如果你需要輸入a=3.0那麼這段代碼將無法正常工作(如a=3.0是一個浮點數)。

2

我碰到這個代碼(即作品)跌跌撞撞:......爲什麼它的工作原理?

它不起作用,一般來說。太多的失敗案例

給定的輸入可以是單個字符Z,後續代碼未定義行爲(UB)作爲scanf()不分配a。結果:(int)a是UB。

scanf("%f",&a); 
q=(int)a; 

給定的輸入可能是「123456789」,東西的int的範圍之外,然後用(int)a轉換也UB。

如果a取值爲INT_MAX,++q;爲UB。

輸入值可以精確地表示爲int而不是float失敗OP的代碼。被四捨五入到整數像"0.99999999999999999999999999999"

輸入 - >1.0f失敗OP的檢測


替代。

scanf(), fgets()不讀C字符串intfloat等取而代之的是,更好地把它們當作閱讀文本並將它們轉換爲C字符串intfloat

f in scanf()意味着格式化輸入,這是未知的部分在這裏。最好避免scanf()

由於代碼需要檢測有關用戶輸入的各種內容,請使用fgets()來讀取文本的。然後使用strtol(),strtoll(),strtoul()等查看輸入是否符合目標類型。

// Check if input fits in a `long` 
char buf[100]; 
if (fgets(buf, sizeof buf, stdin) == NULL) { 
    puts("End-of-file or input error"); 
} else { 
    char *endptr; 
    errno = 0; 
    long ivalue = strtol(buf, &endptr, 0); 
    if (buf == endptr) puts("Fail: no conversion"); 
    else if (*endptr != '\n' && *endptr != '\0') puts("Fail: Extra junk"); 
    else if (errno) puts("Fail: Overlfow"); 
    else printf("Success: %ld\n", ivalue); 
} 
1

這樣的說法:

scanf("%f",&a); 

可以告訴你,你想知道什麼。

調用scanf()系列函數時:始終檢查返回值(不是參數值)以確保操作成功。

在這種情況下建議:

if(1 != scanf("%f",&a)) 
{ // non digit entered 
    .... 
}