C語言中scanf函式的實現

2021-07-15 05:18:01 字數 4766 閱讀 6849

在scanf.c檔案中,可以看到scanf函式,**如下:

#include    #include    #include    "loc_incl.h"

int scanf(const char *format, ...)

對於va_list、va_start、va_end等在stdarg.h標頭檔案中定義的巨集,都已經在(stdarg.h標頭檔案源**分析)一文中介紹過。

在上述**中我們可以看到有乙個_doscan函式,而這一函式在標頭檔案loc_incl.h中定義,函式宣告如下:

int _doscan(file * stream, const char *format, va_list ap);
_doscan函式的實現源**如下:

int

_doscan(register file *stream, const char *format, va_list ap)

if (ic != eof) ungetc(ic,stream);

nrchars--;

}if (!*format) break; /* end of format */

if (*format != '%')

format++;

if (*format == '%')

else break;

}flags = 0;

if (*format == '*')

if (isdigit (*format))

switch (*format)

kind = *format;

if ((kind != 'c') && (kind != '[') && (kind != 'n')) while (isspace(ic));

if (ic == eof) break; /* outer while */

} else if (kind != 'n')

switch (kind)

break;

case 'p': /* pointer */

set_pointer(flags);

/* fallthrough */

case 'b': /* binary */

case 'd': /* decimal */

case 'i': /* general integer */

case 'o': /* octal */

case 'u': /* unsigned */

case 'x': /* hexadecimal */

case 'x': /* ditto */

if (!(flags & fl_widthspec) || width > numlen)

width = numlen;

if (!width) return done;

str = o_collect(ic, stream, kind, width, &base);

if (str < inp_buf

|| (str == inp_buf

&& (*str == '-'

|| *str == '+'))) return done;

/** although the length of the number is str-inp_buf+1

* we don't add the 1 since we counted it already

*/nrchars += str - inp_buf;

if (!(flags & fl_noassign))

break;

case 'c':

if (!(flags & fl_widthspec))

width = 1;

if (!(flags & fl_noassign))

str = va_arg(ap, char *);

if (!width) return done;

while (width && ic != eof)

}if (width)

break;

case 's':

if (!(flags & fl_widthspec))

width = 0xffff;

if (!(flags & fl_noassign))

str = va_arg(ap, char *);

if (!width) return done;

while (width && ic != eof && !isspace(ic))

}/* terminate the string */

if (!(flags & fl_noassign))

*str = '\0';

if (width)

break;

case '[':

if (!(flags & fl_widthspec))

width = 0xffff;

if (!width) return done;

if ( *++format == '^' ) else

reverse = 0;

for (str = xtable; str < &xtable[nr_chars]

; str++)

*str = 0;

if (*format == ']') xtable[*format++] = 1;

while (*format && *format != ']')

else xtable['-'] = 1;}}

if (!*format) return done;

if (!(xtable[ic] ^ reverse))

if (!(flags & fl_noassign))

str = va_arg(ap, char *);

do } while (width && ic != eof && (xtable[ic] ^ reverse));

if (width)

if (!(flags & fl_noassign))

break;

#ifndef nofloat

case 'e':

case 'e':

case 'f':

case 'g':

case 'g':

if (!(flags & fl_widthspec) || width > numlen)

width = numlen;

if (!width) return done;

str = f_collect(ic, stream, width);

if (str < inp_buf

|| (str == inp_buf

&& (*str == '-'

|| *str == '+'))) return done;

/** although the length of the number is str-inp_buf+1

* we don't add the 1 since we counted it already

*/nrchars += str - inp_buf;

if (!(flags & fl_noassign))

break;

#endif

} /* end switch */

conv++;

if (!(flags & fl_noassign) && kind != 'n') done++;

format++;

}return conv || (ic != eof) ? done : eof;

}_doscan函式**

在上面的源**中,值得注意的是第26行的getc巨集,定義**如下:

#define    getc(p)        (--(p)->_count >= 0 ? (int) (*(p)->_ptr++) : \

__fillbuf(p))

getc的呼叫形式:ch=getc(fp); 功能是從檔案指標指向的檔案讀入乙個字元,並把它作為函式值返回給int型變數ch。

第4行~第17行,定義一些後面需要用到的變數

第23行~第

34行,跳過format格式串中的空格,並且跳過輸入流中的空格

第37行~第

42行,輸入流stream與format格式串中的空白符(空白符可以是空格(space)、製表符(tab)和新行符(newline))保持一致

第44行~第

52行,在format中的字元為'%'的前提下,stream中的字元也為'%',則繼續

第54行

~第57行,format當前字元為'*',表示讀指定型別的資料但不儲存

第58行

~第62行,指定說明最大域寬。 在百分號(%)與格式碼之間的整數用於限制從對應域讀入的最大字元數於寬度

第64行

~第282行,switch語句,用於格式修飾符,這些修飾符包括: h、l、l、c、p、b、d、i、o、u……,還有基於掃瞄集的'['修飾符

對scanf函式的原始碼分析,需要在scanf函式的語法格式詳細的理解基礎上進行,由於scanf函式實現十分複雜,需要仔細的品味,這裡只是比較初步的分析,具體還有待後期不斷的完善

cpoint

出處:

C語言中scanf函式

scanf 函式每次讀取乙個字元,跳過所有的空白字元,直至遇到第1個非空白字元才開始讀取。因為要讀取整數,所以 scanf 希望發現乙個數字字元或者乙個符號 或 如果找到乙個數字或符號,它便儲存該字元,並讀取下乙個字元。如果下乙個字元是數字,它便儲存該數字並讀取下乙個字元。scanf 不斷地讀取和儲...

C語言中的scanf函式

思考 如果,我們想拿到使用者輸入的東西,怎麼辦?解決 我們需要使用 scanf 這個函式 1.scanf 的作用 在程式執行到 scanf 的時候,接收使用者輸入的一些資料,並儲存在變數之中 2.scanf 的語法 scanf 格式控制字串 變數位址列表 語義 格式控制字串裡寫佔位符,佔位符用來接收...

C語言中scanf 函式的小結

1.scanf 的返回值 scanf函式是有返回值的,接受乙個變數返回1。如 c scanf d d a,b 若輸入的全是整數,則c為2 若全是字元,則c為0 因為scanf在佔位符存在的情況下,只接受符合佔位符的資料。2.scanf的結束 如果不是 c,則以空格,回車,tab鍵結束,或非法字元結束...