C語(yǔ)言之如何用isspace()和ungetc()實(shí)現(xiàn)前導(dǎo)空白字符過濾
問題場(chǎng)景
當(dāng)使用getchar()
進(jìn)行字符輸入時(shí),我們經(jīng)常需要跳過輸入流開頭位置的空格、制表符、換行符等空白字符,直到遇到第一個(gè)有效字符為止。這在處理用戶輸入或解析文件時(shí)尤為常見。
對(duì)于初學(xué)者來說,在做算法練習(xí)的時(shí)候也會(huì)遇到如先為int類型的變量輸入一個(gè)值,后再輸入一個(gè)字符串的情況。此時(shí)由于不知道兩次輸入之間的空白字符的數(shù)量以及類型,處理前導(dǎo)的空字符便成了一個(gè)稍麻煩的問題。
洛谷許多題目進(jìn)行不同行輸入時(shí)通常采用的是"\r\n"而不是單純的"\n",樓主曾經(jīng)就嘗試使用游離的getchar()處理兩次輸入之間的’\n’,結(jié)果一道橙題折騰了一晚上也沒AC…
關(guān)鍵函數(shù)說明
1. isspace()函數(shù)
#include <ctype.h> int isspace(int c);
- 判斷傳入的字符是否是空白字符
- 支持的空白字符包括:空格(’ ‘)、換頁(yè)符(’\f’)、換行符(‘\n’)、回車符(‘\r’)、水平制表符(‘\t’)、垂直制表符(‘\v’)
2. ungetc()函數(shù)
#include <stdio.h> int ungetc(int c, FILE *stream);
- 將指定字符推回輸入流
- 常用于"偷看"下一個(gè)字符后需要還原的場(chǎng)景
- 最多保證1個(gè)字符的可靠回推
解決方案
#include <stdio.h> #include <ctype.h> void trim_leading_whitespace() { int c; // 跳過所有空白字符,注意這里while后面的分號(hào) while ((c = getchar()) != EOF && isspace(c)); if (c != EOF) { ungetc(c, stdin); // 將第一個(gè)非空白字符放回緩沖區(qū) } }
使用示例:
int main() { printf("請(qǐng)輸入帶空格的字符串:"); trim_leading_whitespace(); int ch; printf("處理后的首字符:"); if ((ch = getchar()) != EOF) { putchar(ch); } // 讀取剩余字符 printf("\n剩余字符:"); while ((ch = getchar()) != '\n' && ch != EOF) { putchar(ch); } return 0; }
運(yùn)行效果:
請(qǐng)輸入帶空格的字符串: Hello World
處理后的首字符:H
剩余字符:ello World
實(shí)現(xiàn)解析
- 循環(huán)讀取:通過
while
循環(huán)持續(xù)讀取字符,直到遇到EOF或非空白字符 - 字符判斷:使用
isspace()
過濾所有類型的空白字符 - 字符回推:檢測(cè)到第一個(gè)非空白字符后,使用
ungetc()
將其放回輸入緩沖區(qū) - 后續(xù)處理:主程序可以正常讀取到過濾后的第一個(gè)有效字符
注意事項(xiàng)
- 回推限制:ANSI C保證至少1個(gè)字符的可靠回推,多個(gè)字符的回推行為取決于具體實(shí)現(xiàn)
- 流類型:適用于所有標(biāo)準(zhǔn)輸入流(stdin)及文件流
- 錯(cuò)誤處理:需考慮EOF的邊界條件
- 編碼兼容:完美處理ASCII編碼,對(duì)寬字符需要改用iswspace()
通過這種組合使用,我們可以優(yōu)雅地實(shí)現(xiàn)輸入流的預(yù)處理,為后續(xù)的字符處理打下良好基礎(chǔ)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++使用string的大數(shù)取模運(yùn)算(5)
這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)取模運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09C++?基本數(shù)據(jù)類型中int、long等整數(shù)類型取值范圍及原理分析
這篇文章主要介紹了C++?基本數(shù)據(jù)類型中int、long等整數(shù)類型取值范圍及原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C++11 簡(jiǎn)單實(shí)現(xiàn)線程池的方法
這篇文章主要介紹了C++11 簡(jiǎn)單實(shí)現(xiàn)線程池的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10詳解計(jì)數(shù)排序算法及C語(yǔ)言程序中的實(shí)現(xiàn)
技術(shù)排序算法與我們普通接觸的冒泡排序和快速排序等基于元素比較的算法不同,在編程中通過C語(yǔ)言的數(shù)組能夠清除地表達(dá)出來,這里我們就來詳解計(jì)數(shù)排序算法及C語(yǔ)言程序中的實(shí)現(xiàn)2016-07-07C語(yǔ)言變長(zhǎng)數(shù)組 struct中char data[0]的用法詳解
下面小編就為大家?guī)硪黄狢語(yǔ)言變長(zhǎng)數(shù)組 struct中char data[0]的用法詳解。小編覺得挺不錯(cuò)的現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01C++中的動(dòng)態(tài)規(guī)劃子序列問題分析探討
可能有些讀者有接觸過動(dòng)態(tài)規(guī)劃,可能也有一些讀者以前完全不知道動(dòng)態(tài)規(guī)劃這個(gè)東西,別擔(dān)心,我這篇文章會(huì)為讀者做一個(gè)入門,好讓讀者掌握這個(gè)重要的知識(shí)點(diǎn)2023-03-03C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單彈球游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02