關於一個 scanf 常見的錯誤

昨晚一同窗發了一段代碼給我,讓我看看在哪裏出錯。也就短短的二十幾行,咱是看了兩三遍,愣是沒有把錯誤的地方給找出來!!!不得已只好把那段代碼個拷貝出來,單獨運行下,發現錯誤就然出如今這兒 scanf("%d %d %d  ", &x, &y, &z); 函數

scanf("%d %d %d", &x, &y, &z); 與 scanf("%d %d %d  ", &x, &y, &z); 一個空白符的差異!!前者爲正常的接收三個數字,後者要求多輸入一個非空白字符。在網上找了好一下子,找的基本上都是說這是一個常見的錯誤,但沒有說明爲何!!! 測試

而後不得與咱只得去看看scanf的解析過程,各類debug,最終定格在input.c 裏面的  int __cdecl _tinput_s_l(FILE* stream, const _TUCHAR* format, _locale_t plocinfo, va_list arglist)  丫的,一個函數一千多行代碼,還不包括各類宏展開,和函數調用!! spa

FILE* stream 爲輸入流,這裏就是 stdin了 debug

_TUCHAR* format  就是解析規則,也就是上面的 "%d %d %d  " orm

略去好多行,直接進入關鍵部分 ci

 while (*format) { //判斷是否到達字符串的結尾


        if (_istspace((_TUCHAR)*format)) {//看着函數名字的意思就是判斷當前字符是否屬於空白字符

            //這個宏的做用就是略過輸入流裏面的空白字符,直到遇到一個非空白字符後返回 字符串

            //固然啦這個非空白字符仍是會繼續放到輸入流中的
            UN_INC(EAT_WHITE()); /* put first non-space char back */

        //這個函數的做用就是略過字符串中的空白字符啦
            do {
                tch = *++format;
            } while (_istspace((_TUCHAR)tch));


            continue;


        }//_if
input


………………………………………… form

}//_while(*format)

看到這裏大概就可以明白爲何一個空白符差異這麼大了:在解析format字符串時,只要遇到空白符,函數就會去過濾掉輸入流中的空白符直到遇到非空白字符。因此在讀到"%d %d %d  "這個字符串中的最後空白符,就會去處理輸入流中的空白符,而回車符和空格都屬於空白符,所以不管你按多少個回車,就是出不告終果,終止的條件是輸入一個非空白字符,因此看上去,你是要輸入4個數字而不是三個數字 stream



上面的測試環境是在vs2008下!!

相關文章
相關標籤/搜索