ASCII码不可见字符过滤处理
Function/Control Code/Character in ASCII
Version: 2011-02-15
Author: green-waste (at) 163.com
【什么是?Function Code?功能碼或??Function Character?功能字符】
ASCII?字符集,大家都知道吧,最基本的包含了?128?個字符。其中前?32?個,?0-31?,即?0x00-0x1F?,都是不可見字符。這些字符,就叫做控制字符。
這些字符沒法打印出來,但是每個字符,都對應著一個特殊的控制功能的字符,簡稱功能字符或功能碼?Function Code?。
簡言之:?ASCII?中前?32?個字符,統稱為?Function Code?功能字符。
此外,由于?ASCII?中的?127?對應的是?Delete?,也是不可見的,所以,此處根據筆者的理解,也可以歸為?Function Code?。
此類字符,對應不同的“功能”,起到一定的“控制作用”,所以,稱為控制字符。
關于每個控制字符的控制功能縮寫,參見下表:
?
表格??1????ASCII?中的控制字符
十 進制 | 十六 進制 | 控制 字符 | 轉義 字符?* | 說明 | Ctrl + 下列字母??* |
0 | 00 | NUL | /0 | Null character(?空字符?) | @ (Shift + 2) |
1 | 01 | SOH | ? | Start of Header(?標題開始?) | A |
2 | 02 | STX | ? | Start of Text(?正文開始?) | B |
3 | 03 | ETX | ? | End of Text(?正文結束?) | C |
4 | 04 | EOT | ? | End of Transmission(?傳輸結束?) | D |
5 | 05 | ENQ | ? | Enquiry(?請求?) | E |
6 | 06 | ACK | ? | Acknowledgment(?收到通知?/?響應?) | F |
7 | 07 | BEL | /a | Bell?(?響鈴?) | G |
8 | 08 | BS | /b | Backspace(?退格?) | H |
9 | 09 | HT | /t | Horizontal Tab(?水平制表符?) | I |
10 | 0A | LF | /n | Line feed(?換行鍵?) | J |
11 | 0B | VT | /v | Vertical Tab(?垂直制表符?) | K |
12 | 0C | FF | /f | Form feed(?換頁鍵?) | L |
13 | 0D | CR | /r | Carriage return(?回車鍵?) | M |
14 | 0E | SO | ? | Shift Out(?不用切換?) | N |
15 | 0F | SI | ? | Shift In(?啟用切換?) | O |
16 | 10 | DLE | ? | Data Link Escape(?數據鏈路轉義?) | P |
17 | 11 | DC1 | ? | Device Control 1(?設備控制?1) /XON(Transmit On) | Q |
18 | 12 | DC2 | ? | Device Control 2(?設備控制?2) | R |
19 | 13 | DC3 | ? | Device Control 3(?設備控制?3) /XOFF(Transmit Off) | S |
20 | 14 | DC4 | ? | Device Control 4(?設備控制?4) | T |
21 | 15 | NAK | ? | Negative Acknowledgement(?拒絕接收?/?無響應?) | U |
22 | 16 | SYN | ? | Synchronous Idle(?同步空閑?) | V |
23 | 17 | ETB | ? | End of Trans the Block(?傳輸塊結束?) | W |
24 | 18 | CAN | ? | Cancel(?取消?) | X |
25 | 19 | EM | ? | End of Medium(?已到介質末端?/?介質存儲已滿?) | Y |
26 | 1A | SUB | ? | Substitute(?替補?/?替換?) | Z |
27 | 1B | ESC | /e | Escape(?溢出?/?逃離?/?取消?) | [ |
28 | 1C | FS | ? | File Separator(?文件分割符?) | / |
29 | 1D | GS | ? | Group Separator(?分組符?) | ] |
30 | 1E | RS | ? | Record Separator(?記錄分隔符?) | ^ (Shit + 6) |
31 | 1F | US | ? | Unit Separator(?單元分隔符?) | _ (Shift + -) |
32 | 20 | SP | ? | White space | [Space] * |
127 | 7F | DEL | ? | Delete(?刪除?) | [Delete] * |
注?(*)?:
1.??轉義字符:即在?C?語言中或其他地方如何表示。
2.??用鍵盤輸入控制字符:其中,?32?是空格鍵,?127?是?Delete?鍵,都不需要加?Ctrl?鍵,即可直接輸入。
3.??可以通過??“Ctrl+?對應按鍵?”?實現上述控制字符的輸入?,??你可能遇到的一些,比如?:?用?Ctrl+V?輸入?SYNC?,?Ctrl+M?輸入Enter?(當然也可以直接用?Enter?鍵,但是在?Windows?下面,其可能會發送兩個字符:?CR?和?LF?),?Ctrl+Q?輸入?XON?,Ctrl+S?輸入?XOFF?等等。
?【過濾處理】
在Qt中,QChar有一個函數是isPrint(),判斷是否為打印字符,可以直接使用
?
其具體每個控制字符的含義,詳解介紹如下:
【?ASCII?中的?Function/Control Code?功能字符的詳細含義】
?
0 – NUL –?NUL?l??字符?/?空字符
ASCII?字符集中的空字符,?NULL?,起初本意可以看作為?NOP?(中文意為空操作,就是啥都不做的意思),此位置可以忽略一個字符。
之所以有這個空字符,主要是用于計算機早期的記錄信息的紙帶,此處留個?NUL?字符,意思是先占這個位置,以待后用,比如你哪天想起來了,在這個位置在放一個別的啥字符之類的。
后來呢,?NUL?字符被用于?C?語言中,字符串的終結符,當一個字符串中間出現?NUL / NULL?,代碼里面表現為?/0?,的時候,就意味著這個是一個字符串的結尾了。這樣就方便按照自己需求去定義字符串,多長都行,當然只要你內存放得下,然后最后加一個?/0,??即空字符,意思是當前字符串到此結束。
?
1 – SOH –?S?tart???O?f?H?eading??標題開始
如果信息溝通交流主要以命令和消息的形式的話,?SOH?就可以用于標記每個消息的開始。
1963?年,最開始?ASCII?標準中,把此字符定義為?Start of Message?,后來又改為現在的?Start Of Heading?。
現在,這個?SOH?常見于主從(?master-slave?)模式的?RS232?的通信中,一個主設備,以?SOH?開頭,和從設備進行通信。這樣方便從設備在數據傳輸出現錯誤的時候,在下一次通信之前,去實現重新同步(?resynchronize?)。如果沒有一個清晰的類似于?SOH?這樣的標記,去標記每個命令的起始或開頭的話,那么重新同步,就很難實現了。
?
2 – STX –?S?tart?O?f?T?ext??文本開始
3 – ETX –?E?nd Of?T?ext??文本結束
通過某種通訊協議去傳輸的一個數據(包),稱為一幀的話,常會包含一個幀頭,包含了尋址信息,即你是要發給誰,要發送到目的地是哪里,其后跟著真正要發送的數據內容。
而?STX?,就用于標記這個數據內容的開始。接下來是要傳輸的數據,最后是?ETX?,表明數據的結束。
其中,中間具體傳輸的數據內容,?ASCII?規范并沒有去定義,其和你所用的傳輸協議,具體自己要傳什么數據有關。
?
幀頭 | 數據或文本內容 | ? | ? | |
SOH(表明幀頭開始) | 。。。。(幀頭信息,比如包含了目的地址,表明你發送給誰等等) | STX?(表明數據開始) | 。。。(真正要傳輸的數據) | ETX?(表明數據結束) |
| ? | ? | ? | ? | ? |
?
?
不過其中有趣的是,?1963?年,?ASCII?標準最初版本的時候,把現在的?STX?叫做?EOA?(?End Of Address?),?ETX?叫做(End Of Message?)。這是因為,最早的時候,一個消息中,總是包含一個開始符和一個終止符。現在的新的定義,使得可以去發送一個固定長度的命令,而只用一個?SOH?表明幀頭開始即可,而不需要再加上一個命令終止符或幀頭結束符。
?
總結一下:
一般發送一個消息,包含了一個幀頭和后面真正要傳的數據。
而對于幀頭,屬于控制類的信息,這部分之前屬于命令,后面的真實要傳的數據屬于數據。即消息?=?幀頭?+?數據。
而之前的命令都要有個開始符和結束符,這樣就是:
消息????????=??幀頭????????????????????????????????+??要傳的數據
=??幀頭開始?+?幀頭信息?+?幀頭結束?????????+??要傳的數據
而現在新的定義,使得只需要:
消息????????=??幀頭??+?要傳的數據
= SOH?(表明幀頭開始)?+?幀頭信息?????+??要傳的數據
= SOH?(表明幀頭開始)?+?幀頭信息?????+ STX +??數據內容?+ETX
就可以少用一個幀頭結束符。
?
而如今,在很多協議中,也常見到,一個固定長度的幀頭,后面緊接著就是數據了,而沒有所謂的幀頭結束符之類的東西去區分幀頭和數據。
?
4 – EOT –?E?nd?O?f?T?ransmission??傳輸結束
5 – ENQ –?ENQ?uiry??請求
6 – ACK –?ACK?nowledgment??回應?/?響應
7 – BEL – [audible]?BEL?l
?
在?ASCII?字符集中,?BEL?,是個比較有意思的東東。因為其原先本意不是用來數據編碼的,于此相反,?ASCII?中的其他字符,都是用于字符編碼(即用什么字符,代表什么含義)或者起到控制設備的作用。?BEL?用一個可以聽得見的聲音,來吸引人們的注意,其原打算即用于計算機也用于一些設備,比如打印機等。?C?語言里面也支持此?BEL?,用?/a?來實現這個響鈴。
?
8 – BS –?B?ackS?pace??退格鍵
退格鍵的功能,隨著時間變化,意義也變得不同了。
起初,意思是,在打印機和電傳打字機上,往回移動一格光標,以起到強調該字符的作用。比如你想要打印一個?a?,然后加上退格鍵后,就成了?aBS^?。在機械類打字機上,此方法能夠起到實際的強調字符的作用,但是對于后來的?CTR?下時期來說,就無法起到對應效果了。
而現代所用的退格鍵,不僅僅表示光標往回移動了一格,同時也刪除了移動后該位置的字符。在?C?語言中,退格鍵可以用/b?表示。
?
9 – HT –?H?orizontal?T?ab??水平制表符
ASCII?中的?HT?控制符的作用是用于布局的。
其控制輸出設備前進到下一個表格去處理。而制表符?Table/Tab?的寬度也是靈活不固定的,只不過,多數設備上,制表符Tab?的寬度都預定義為?8?。水平制表符?HT?不僅能減少數據輸入者的工作量,對于格式化好的文字來說,還能夠減少存儲空間,因為一個?Tab?鍵,就代替了?8?個空格,所以說省空間。
對于省空間的優點,我們現在來看,可能會覺得可笑,因為現在存儲空間已足夠大,一般來說根本不會需要去省那么點可憐的存儲空間,但是實際上在計算機剛發明的時候,存儲空間(主要指的是內存)極其有限也極其昂貴,而且像?ZIP?等壓縮方法也還沒發明呢,所以對于當時來說,對于存儲空間,那是能夠省一點是一點,省任何一點,都是好的,也都是不容易的,省空間就是省錢啊。
C?語言中,用?/t?表示制表符。
?
10 – LF –?L?ine?F?eed??換行
LF?,直譯為(給打印機等)喂一行,意思就是所說的,換行。
換行字符,是?ASCII?字符集中,被誤用的字符中的其中一個。
LF?的最原始的含義是,移動打印機的頭到下一行。而另外一個?ASCII?字符,?CR?(?Carriage Return?)才是將打印機的頭,移到最左邊即一行的開始,行首。很多串口協議和?MS-DOS?及?Windows?操作系統,也都是這么實現的。
而于此不同,對于?C?語言和?Unix?操作系統,其重新定義了?LF?字符的含義為新行,即?LF?和?CR?的組合才能表達出的,回車且換行的意思。
雖然你可以爭論哪種用法是錯的,但是,不可否認,是從程序的角度出發,?C?語言和?Unix?對此?LF?的含義實現顯得就很自然,而?MS-DOS?的實現更接近于?LF?的本意。
如果最開始?ASCII?標準中,及定義??CF?也定義?newline?,那樣意思會清楚,會更好理理解:
LF?表示物理上的,設備控制方面的移動到下一行(并沒有移動到行首);
新行(?newline?)表示邏輯上文本分隔符,即回車換行。
不過呢,現在人們常將?LF?用做?newline?新行的功能,而大多數文本編輯軟件也都可以處理單個?LF?或者?CR/LF?的組合了。
LF?在?C?語言中,用?/n?表示。
?
11 – VT –?V?ertical?T?ab??垂直制表符
垂直制表符,類似于水平制表符?Tab?,目的是為了減少布局中的工作,同時也減少了格式化字符時所需要存儲字符的空間。?VT?控制碼用于跳到下一個標記行。說實話,還真沒看到有些地方需要用這個?VT?呢,因為一般在換行的時候,都是用?LF?代替?VT?了。
?
12 – FF –?F?orm?F?eed???換頁
設計換頁鍵,是用來控制打印機行為的。當打印機收到此鍵碼的時候,打印機移動到下一頁。不同的設備的終端對此控制碼所表現的行為各不同。有些會去清除屏幕,而其他有的只是顯示?^L?字符或者是只是新換一行而已。?Shell?腳本程序Bash?和?Tcsh?的實現方式是,把?FF?看作是一個清除屏幕的命令。?C?語言程序中用?/f?表示?FF?(換頁)。
?
13 – CR – Carriage return??機器的滑動部分?/?底座???返回??->??回車
CR?回車的原意是讓打印頭回到左邊界,并沒有移動到下一行。
隨著時間流逝,后來人把?CR?的意思弄成了?Enter?鍵,用于示意輸入完畢。在數據以屏幕顯示的情況下,人們在?Enter?的同時,也希望把光標移動到下一行。因此?C?語言和?Unix?操作系統,重新定義了?LF?的意思,使其表示為移動到下一行。當輸入?CR?去存儲數據的時候,軟件也常常隱式地將其轉換為?LF?。
?
14 – SO –?S?hift?O?ut??不用切換
15 – SI –?S?hift?I?n???啟用切換
早在?1960s?年代,定義?ASCII?字符集的人,就已經懂得了,設計字符集不單單可以用于英文字符集,也要能應用于外文字符集,是很重要的。
定義?Shift In??和?Shift Out?的含義,即考慮到了此點。
最開始,其意為在西里爾語和拉丁語之間切換。西里爾?ASCII?定義中,?KOI-7?用到了?Shift?字符。拉丁語用?Shift?去改變打印機的字體。在此種用途中,?SO?用于產生雙倍寬度的字符,而用?SI?打印壓縮的字體。
?
16 – DLE –?D?ata?L?ink?E?scape??數據鏈路轉義
有時候,我們需要在正在進行的通信過程中去發送一些控制字符。但是,總有一些情況下,這些控制字符卻被看成了普通的數據流,而沒有起到對應的控制效果。而?ASCII?標準中,定義?DLE?來解決這類問題。
如果數據流中檢測到了?DLE?,數據接收端則對其后面接下來的數據流中的字符,另作處理。而關于具體如何處理這些字符,?ASCII?規范中則沒有具體定義,而只是弄了個?DLE?去打斷正常數據的處理,告訴接下來的數據,要特殊對待。根據Modem?中的?Hayes?通信協議?DLE?定義為“無聲?+++?無聲”。以我的觀點,這樣可能會更好:如果?Hayes?協議沒有把DLE?處理為嵌入通訊的無聲狀態,那樣就符合現存的標準了。然而?Hayes?的開發者卻覺得?+++?用的頻率要遠高于原始的DLE?,所以才這么定義了。
?
17 – DC1 –?D?evice?C?ontrol 1 / XON – Transmission on
這個?ASCII?控制字符盡管原先定義為?DC1?,???但是現在常表示為?XON?,用于串行通信中的軟件流控制。其主要作用為,在通信被控制碼?XOFF?中斷之后,重新開始信息傳輸。用過串行終端的人應該還記得,當有時候數據出錯了,按?Ctrl+Q(等價于?XON?)有時候可以起到重新傳輸的效果。這是因為,此?Ctrl+Q?鍵盤序列實際上就是產生?XON?控制碼,其可以將那些由于終端或者主機方面,由于偶爾出現的錯誤的?XOFF?控制碼而中斷的通信解鎖,使其正常通信。
?
18 – DC2 –?D?evice?C?ontrol 2
19 – DC3 –?D?evice?C?ontrol 3 / XOFF – Transmission off??傳輸中斷
20 – DC4 –?D?evice?C?ontrol 4
21 – NAK –?N?egative?A?cK?nowledgment??負面響應?->??無響應?,??非正常響應
22 – SYN –?SYN?chronous idle
23 – ETB –?E?nd of?T?ransmission?B?lock??塊傳輸中止
24 – CAN –?CAN?cel??取消
25 – EM –?E?nd of?M?edium???已到介質末端,介質存儲已滿
EM?用于,當數據存儲到達串行存儲介質末尾的時候,就像磁帶或磁頭滾動到介質末尾一樣。其用于表述數據的邏輯終點,即不必非要是物理上的達到數據載體的末尾。
?
26 – SUB –?SUB?stitute character?替補?/?替換
27 – ESC –?ESC?ape??逃離?/?取消
字符?Escape?,是?ASCII?標準的首創的,由?Bob Bemer?提議的。用于開始一段控制碼的擴展字符。如此,即可以不必將所有可能想得到的字符都放到?ASCII?標準中了。因為,新的技術可能需要新的控制命令,而?ESC?可以用作這些字符命令的起始標志。?ESC?廣泛用于打印機和終端,去控制設備設置,比如字體,字符位置和顏色等等。如果最開始的?ASCII?標準中,沒有定義?ESC?,估計?ASCII?標準早就被其他標準所替代了,因為其沒有包含這些新出現的字符,所以肯定會有其他新的標準出現,用于表示這些字符的。即,?ESC?給開發者提供了,可以根據需要而定義新含義的字符的可能。
?
28 – FS –?F?ile?S?eparator??文件分隔符
文件分隔符是個很有意思的控制字符,因為其可以讓我們看到?1960s?年代的時候,計算機技術是如何組織的。我們現在,習慣于隨即訪問一些存儲介質,比如?RAM?,磁盤,但是在定義?ASCII?標 準的那個年代,大部分數據還是順序的,串行的,而不是隨機訪問的。此處所說的串行的,不僅僅指的是串行通信,還指的是順序存儲介質,比如穿孔卡片,紙帶, 磁帶等。在串行通信的時代,設計這么一個用于表示文件分隔符的控制字符,用于分割兩個單獨的文件,是一件很明智的事情。而?FS?的原因就在于此。
?
29 – GS –?G?roup?S?eparator?分組符
ASCII?定義控制字符的原因中,其中一條就是考慮到了數據存儲方面的情況。大部分情況下,數據庫的建立,都和表有關,包含了對應的記錄。同一個表中的所有的記錄,屬于同一類型。不同的表中的記錄,屬于對應的不同的類型。而分組符?GS?就是用來分隔串行數據存儲系統中的不同的組。值得注意的是,當時還沒有使用?word?的表格,當時?ASCII?時代的人,把他叫做組。
?
30 – RS –?R?ecord?S?eparator?記錄分隔符
記錄分隔符?RS?用于分隔在一個組或表內的多個記錄。
?
31 – US –?U?nit?S?eparator??單元分隔符
在?ASCII?定義中,在數據庫中所存儲的,最小的數據項,叫做?Unit?單元。而現在我們稱其?field?域。單元分隔符?US?用于分割串行數據存儲環境下的不同的域。
現在大部分的數據庫實現,要求大部分類型都擁有固定的長度。
盡管大部分時候可能用不到,但是對于每一個域,卻都要分配足夠大的空間,用于存放最大可能的成員變量。這樣的做法,占用了大量的存儲空間,而?US?控制碼允許域具有可變的長度。在?1960s?年代,數據存儲空間很有限,用?US?這個單元分隔符,將不同單元分隔開,這樣就可以實現更高效地存儲那些寶貴的數據。另一方面,串行存儲的存儲效率,遠低于RAM?和磁盤中所實現的表格存儲。我個人無法想象,如果現在的數據,還是存儲在自帶或者帶滾輪的磁帶上,會是何種景象。
?
32 – SP – White?SP?ace??空格鍵
也許你會爭論說,空格鍵是否真的能算是一個控制字符?因為現在在普通文字中使用空格鍵是如此常見。
但是,既然水平制表符和退格鍵在?ASCII?中, 都被叫做控制字符了,那么我覺得也很自然地,可以把空格鍵(向前的空格)也叫做控制字符,畢竟,其本身并不代表一個真正的可見的字符,而僅僅只是很常用于 輸出設備,用于處理位置前向移動一格,清除當前位置的內容而已。在很多程序中,比如字符處理程序,白空格同樣可能從導致行尾轉到下一行行首,而網絡瀏覽器 將多個空格組合成單個空格輸出。
所以,這更加堅定了我的想法,覺得完全可以把空格看成是一個控制字符,而不僅僅是一個很獨特的普通字符。
?
127 – DEL –?DEL?ete???刪除
有人也許會問,為何?ASCII?字符集中的控制字符的值都是很小的,即?0-32?,而?DEL?控制字符的值卻很大,是?127?。這是由于這個特殊的字符是為紙帶而定義的。而在那個時候,絕大多數的紙帶,都是用?7?個孔洞去編碼數據的。而?127?這個值所對應的二進制值為?111 1111b?,表示所有?7?個比特位都是高,所以,將?DEL?用在現存的紙帶上時,所有的洞就都被穿孔了,就把已經存在的數據都擦出掉了,就起到了對應的刪除的作用了。
?
【引用】
1?.??ASCII character map
http://www.lammertbies.nl/comm/info/ascii-characters.html
?
2?.???百度百科:?ASCII
http://baike.baidu.com/view/15482.htm
?
3.??ASCII?編碼表
http://www.dreamdu.com/xhtml/ascii/
總結
以上是生活随笔為你收集整理的ASCII码不可见字符过滤处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 何处是我家
- 下一篇: 基于SSM流浪宠物管理系统