🚀 作者:阿輝不一般
🚀 你說呢:不服輸的你,他們拿什么贏
🚀 專欄:愛上C語言
🚀作圖工具:draw.io(免費開源的作圖網站)
如果覺得文章對你有幫助的話,還請點贊,關注,收藏支持博主,如有不足還請指點,博主及時改正,感謝大家支持!!!
文章目錄
- 🚀前言
- 🚀輸入緩沖區
- 🚀scanf()函數
- 🚀gets()函數
- 🚀getchar()函數
- ??清空輸入緩沖區
🚀前言
大家好啊😉!今天阿輝將為大家介紹C語言中scanf、gets以及getchar關于字符串的輸入,關注阿輝不迷路哦 😘 ,內容干貨滿滿😋,接下來就跟著阿輝一起學習吧👊
🚀輸入緩沖區
輸入緩沖區是計算機系統中用于存儲輸入數據的一種緩沖區
怎么理解他呢,比如我們C語言中的scanf
以及今天阿輝要介紹的函數,他們并非直接讀取我們在鍵盤上敲的數據,而是我們敲的數據先存在緩沖區內,然后scanf
從緩沖區里面讀取的
注意:
上面的圖只是簡單的描述,輸入緩沖區就像你的飯卡你往里面充錢,一次可能充100塊,但是scanf這頓飯可能就只讀12塊
阿輝今天要講的就是scanf、gets、getchar以及fgets在緩沖區中是如何讀取的
輸入緩沖區的數據一旦被讀取就不再輸入緩沖區了
🚀scanf()函數
scanf()
相信大家都不陌生,他就是通過占位符從標準輸入流中格式化的讀取數據然后把數據存儲在參數所指向的位置
1.標準輸入流默認是鍵盤輸入
2.參數就是地址,例如&a
這樣
我們來看一個🌰栗子
#include<stdio.h>int main()
{int a = 0;int b = 0;scanf("%d%d", &a, &b);printf("a = %d b = %d\n", a, b);scanf("%d%d", &a, &b);printf("a = %d b = %d\n", a, b);return 0;
}
注意:只要scanf
不是使用%c
讀取數據時,數據前面的空白字符(空格、制表符以及換行)都會被忽略
好吧以上都不是重點😆,重點是對于字符串的讀取
上星期一道牛客OJ題給阿輝整的汗流浹背(點擊可跳轉)
題目:
輸入描述:
輸入一個字符串,可以有空格輸出描述:
輸出逆序的字符串示例1
輸入
I am a student
輸出
tneduts a ma I
關于這道題的代碼
#include <stdio.h>
#include <string.h>void reverse(char *p, int sz) {int i = 0;int j = sz - 1;for (i = 0, j = sz - 1; i < sz / 2; i++, j--) {char tmp = *(p + i);*(p + i) = *(p + j);*(p + j) = tmp;}
}int main()
{char arr[10000] = {0};int i = 0;scanf("%[^\n]%*c",arr);int sz = strlen(arr);reverse(arr, sz);printf("%s", arr);return 0;
}
孤陋寡聞的阿輝只會用scanf
用%s
讀,而%s
遇到空格換行制表符就會停止讀取,用%c
讀,換行\n
都給我讀來了我靠真的汗流浹背了,阿輝急忙翻題解,我丟這題解真是讓人兩眼放光😍,gets
還有scanf
的高級用法
scanf
讀字符串的神仙用法:
scanf
可以通過字符集的方式讀取字符scanf("%[a-z]",str)
,a-z
指的是只讀取a到z之間的小寫字母,遇到非范圍內的字符停止讀取,當然你也可以用[A-Z]
只讀大寫字母,范圍自定義scanf("%[ ^\n ]",str)
,^\n
指的是只讀取非\n
的字符包括制表符和空格,遇到換行停止讀取,當然你也可以^\t
,都是是自定義的scanf("%*c",str)
,*
指的是對于一個字符類型的數據只讀取但不存儲給任何變量,就是把這個數據從輸入緩沖區去掉這一個操作,也可以%*d
,也是自定義的
🌰栗子
int main()
{char str1[10] = { 0 };char str2[10] = { 0 };scanf("%[a-z]", str1);scanf("%[^\n]", str2);printf("%s\n", str1);printf("%s", str2);return 0;
}
輸入:
abcd1換行
輸出:
abcd --第一行
1 --第二行
因為第一個
scanf
只讀取a-z
之間的數據,讀到1停止讀取,而1后面還有一個換行,1和換行都還在輸入緩沖區內,因為第二個scanf
讀到換行就會停止讀取,因為輸入緩沖區有換行了,你連鍵盤輸入的機會都沒有了,這里\n
還留在輸入緩沖區
這里我們對輸入緩沖區的理解應該更加清晰了,scanf
從緩沖區讀取數據,輸入緩沖區有適合的數據就不需要你輸入了,就像你飯卡有錢就不用充錢了
如果我們這么寫
int main()
{char str1[10] = { 0 };char str2[10] = { 0 };scanf("%[a-z]%*d%*c", str1);scanf("%[^\n]%*c", str2);printf("%s\n", str1);printf("%s", str2);return 0;
}
輸入:
abcd1換行
ab123換行
輸出;
abcd --第一行
ab123 --第二行
這里第一個
scanf
里面的%*d%*c
將1和換行\n
給讀取了但并未賦給任何變量,我的理解就是把輸入緩沖區一個有符號數和一個字符給刪掉,然后到第二個scanf
的時候輸入緩沖區就沒數據了得我們自己輸入
🚀gets()函數
gets
這個函數并不會檢查輸入的長度,可能導致緩沖區溢出,并不建議大家使用,可能出bug,不過gets這個函數還是很猛的。
用法:
char *gets(char *str);
str指向字符數組的指針
返回值,讀取成功為str,讀取錯誤為EOF
gets(str)
只能讀取字符包括空格和制表符直到遇到換行符或者文件結束符停止讀取然后將\n
從輸入緩沖區刪除,相當于scanf("%[ ^\n ]%*c",str)
🚀getchar()函數
getchar()
從鍵盤獲取一個字符,返回值也是這個字符,無參數,直到用戶按下回車鍵或輸入的字符達到了緩沖區的最大長度,停止讀取,一次只讀取一個字符包括空格、換行和制表符,相當于scanf("%c",c)
??清空輸入緩沖區
利用getchar()
我們可以寫一個清空輸入緩沖區的函數
void clearbuffer(void)
{while (getchar() != '\n'){;}
}int main()
{char str1[10];char str2[10];scanf("%s", str1);clearbuffer();scanf("%s", str2);printf("str1 = %s\n", str1);printf("str2 = %s\n", str2);return 0;
}
輸入輸出
1234\n
都被clearbuffer
這個函數讀取了,從輸入緩沖區清除了
這里while判斷的條件是
getchar != ‘\n’
,getchar
讀取到哪個字符,它的返回值就是哪個字符,所以,這里我們這樣來清空緩沖區,是連帶\n
一起清理掉的(當getchar()吸收了’\n’,則getchar() == ‘\n’ ,不滿足條件就退出while循環了)
到這里,阿輝今天對于C語言中的scanf、gets以及getchar分享就結束了,希望這篇博客能讓大家有所收獲, 如果覺得阿輝寫得不錯的話,記得給個贊唄,你們的支持是我創作的最大動力🌹