1. 程式人生 > >Gets和scanf的區別

Gets和scanf的區別

char s[20]; gets(s); puts(s);

gets與scanf輸入字串的方式也非常類似,但是有幾個區別:

(1) gets的輸入分割符只有回車,因此gets是能夠讀入空格的。如果輸入為"hello world"時,上面程式的執行結果是"hello world"。而如果用scanf則只能輸出hello

(2) 此外,scanf和gets對待緩衝區裡的回車符也是完全不同的。scanf在讀取非空白符之前會忽略回車,讀取之後如果遇到回車會停止輸入,將其留著緩衝區裡;gets只要一遇到回車就輸入結束,並把這個回車從緩衝區裡移走。

(3) gets可以讀取空回車,但是scanf不能。

例如輸入為"\nhello\n",也就是說,先輸入一個空行,然後在第二行輸入"hello"並回車。scanf按照它的讀取原理,把第一個’\n’作為空白符忽略掉,然後讀取字串"hello",遇到第二個’\n’時輸入結束,但是第二個’\n’會被scanf殘留在緩衝區裡。scanf的輸入結果是讀入字串"hello"。當用gets進行讀取時,它遇到第一個’\n’,就找到了它的輸入分隔符,停止繼續輸入,第一個’\n’被從緩衝區中讀走了,緩衝區裡剩下"

gets從標準輸入裝置讀字串函式。可以無限讀取,不會判斷上限,以回車結束讀取,所以程式設計師應該確保buffer的空間足夠大,以便在執行讀操作時不發生溢位。

功能

編輯

從stdio流中讀取字串,直至接受到換行符或EOF時停止,並將讀取的結果存放在buffer指標所指向的字元陣列中。換行符不作為讀取串的內容,讀取的換行符被轉換為‘\0’空字元,並由此來結束字串。

返回值

編輯

讀入成功,返回與引數buffer相同的指標;讀入過程中遇到EOF(End-of-File)或發生錯誤,返回NULL指標。所以在遇到返回值為NULL的情況,要用ferrorfeof函式檢查是發生錯誤還是遇到EOF。

注意

編輯

本函式可以無限讀取,不會判斷上限,所以程式設計師應該確保buffer的空間足夠大,以便在執行讀操作時不發生溢位。如果溢位,多出來的字元將被寫入到

堆疊中,這就覆蓋了堆疊原先的內容,破壞一個或多個不相關變數的值。這個事實導致gets函式只適用於玩具程式,為了避免這種情況,我們可以用fgets(stdin) (fgets實際上可以讀取標準輸入(即大多數情況下的鍵盤輸入),具體參閱fgets詞條)來替換gets()。在V7的手冊(1979年)中說明:為了向後相容,gets刪除換行符,gets並不將換行符存入緩衝區

由於可以無限讀取,所以在2011年12月,ANSI 採納了 ISO/IEC 9899:2011 標準,標準中刪除了 gets()函式,使用一個新的更安全的函式gets_s()替代(具體用法看下面示例)。

示例

編輯

C:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include <stdio.h>    //這個標頭檔案包含gets()函式,這個函式在ISO/IEC 9899 2011(C11)標準中被移除

int main(void)

{

char str1[5];  //不要char*p,然後gets(p),這是錯誤的,因為p沒有指向有效的記憶體,它可能指向任何非法地址                   //     地方的未知大小的記憶體塊,這樣以來,就可能修改了不屬於本程式的記憶體的內容

gets(str1);

printf("%s\n", str1);

return 0;

}

#include <stdio.h>//gets_s()用法

#define CH 20

int main(void)

{

char ch[CH];

printf("請輸入你的名字:\n");

gets_s(ch,CH);             //這裡不能用gets_s(ch);

printf("這是你的名字:%s\n", ch);

return 0;

}

C++:

1

2

3

4

5

6

7

8

9

10

#include <iostream>

#include <cstdio>

using namespace std;

int main()

{

char str[100];

gets(str);

cout<<str<<endl;

return 0;

}

gets()函式用來從標準輸入裝置(鍵盤)讀取字元串直到換行符結束,但換行符會被丟棄,然後在末尾新增'\0'字元。其呼叫格式為:

gets(s);

其中s為字串變數(字串陣列名或字串指標)。

gets(s)函式與scanf("%s",s)相似,但不完全相同,使用scanf("%s",s) 函式輸入字串時存在一個問題,就是如果輸入了空格會認為字串結束,空格後的字元將作為下一個輸入項處理,但gets()函式將接收輸入的整個字串直到遇到換行為止。

也就是說:gets()函式讀取到\n(我們輸入的回車)於是停止讀取,但是它不會把\n包含到字串裡面去。然而,和它配合使用的puts函式,卻在輸出字串的時候自動換行。

說明

編輯

gets(s) 函式中的變數s為一字元串指標。如果為單個字元指標,編譯連線不會有錯誤,但執行後記憶體溢位錯誤。

寬字元版本,當使用unicode寬字元文字時,使用這個函式 _getws();

在C11標準中被刪除,可用C標準庫中的fgets代替.

hello\n"。gets的輸入結果是一個空串,即一個首字元是’\0’的字串。