簡體   English   中英

使用scanf輸入字符並將其保存為int會導致未定義的行為?

[英]entering a char using scanf and saving it in an int can cause undefined behaviour?

我正在編寫代碼,嘗試輸入一個char而不是整數,無論​​輸入的字符如何,結果均為'2',這是未定義的行為還是其他原因?

編碼:

#include <stdio.h>
int f1(int n);
int f2(void);

int main(void)
{
    int t;

    printf("Enter a number: ");
    scanf("%d", &t);
    /* print proper message */
    t ? f1(t) + f2() : printf("zero entered.\n");
    return 0;
}

int f1(int n)
{
    printf("%d ", n);
    return 0;
}

int f2(void)
{
    printf("entered.\n");
    return 0;
}

當我輸入a ,結果為“ 2輸入”,當我輸入g ,結果為“ 2輸入”,而當我輸入i,h,k,..... ,結果是相同的。 那是什么?

如果scanf()遇到無法根據指定的格式字符串進行解析的內容,它只會停止並提早返回。 因此,它永遠不會向t寫入任何內容(您只是看到在調用之前t具有任何不確定的值)。

要處理此問題,您應該始終檢查scanf返回值。

正如您所說,問題是使用%d格式的scanf要求您輸入一個或多個ascii數字。 它停止以非數字字符掃描輸入,因此它從不讀取您鍵入的內容,並且t具有調用scant之前的值。

您需要檢查scanf的返回碼。 看一下聯機幫助頁

返回值

這些函數返回成功匹配和分配的輸入項的數量,該數量可能少於所提供的數量,在早期匹配失敗的情況下甚至為零。

如果在第一次成功轉換或匹配失敗發生之前到達輸入結束,則返回EOF值。 如果發生讀取錯誤,也會返回EOF,在這種情況下,將設置流的錯誤指示符(請參見ferror(3)),並且設置errno表示錯誤。

換句話說, scanf不會將任何內容寫入t ,而是一直未初始化。

因此,代替此:

scanf("%d", &t);

嘗試這個:

int items_matched = scanf("%d", &t);
if (items_matched != 1) {
    printf("bad number entered\n");
    exit(1);
}

這是因為scanf無法解析您的輸入。 由於您使用%d因此希望您輸入一個十進制數字

您必須檢查scanf的返回值以避免這種行為:

成功時,該函數返回已成功填充的參數列表的項目數。 由於匹配失敗,讀取錯誤或文件結尾的范圍,此計數可以與預期的項目數匹配或更少(甚至為零)。

因此:

int items_matched;

// ...
items_matched = scanf("%d", &t);   // Get the return value

if ( items_matched != 1 )          // Check it
{
    printf("Matching failure with scanf.\n");
    return 0;
}
else
{
    if ( t == 0 )
        printf("zero entered\n");
    else
        printf("%d entered\n", t);
}

您不需要令人困惑的f1(t) + f2()

Linux手冊頁

格式字符串由一系列指令組成,這些指令描述了如何處理輸入字符的序列。 如果指令處理失敗,則不會再讀取任何輸入 ,並且scanf()返回。 “失敗”可以是以下之一:輸入失敗(表示輸入字符不可用)或匹配失敗(表示輸入不合適)。

在scanf( 7.21.6.4 scanf函數 )的C11標准描述中:

如果在第一次轉換(如果有的話)完成之前發生輸入失敗,scanf函數將返回宏EOF的值。 否則,scanf函數將返回分配的輸入項目數, 如果早期匹配失敗 ,該數目可能少於所提供的輸入項數, 甚至為零

重點是我的。 因此,正如@oli charlesworth所說,如果有疑問,應檢查scanf的返回值:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM