Pascal 程式設計/輸入輸出
我們從第一章開始就已經使用 I/O 了,但只是為了入門。現在該深入一點了,這樣我們就可以編寫更漂亮的程式。
在鼎盛時期,Pascal 非常聰明,它定義了一個最小公用且方便的介面來與 I/O 互動。儘管各種標準化工作,但 I/O 操作在每個 OS 中都不相同,但作為語言的一部分,Pascal 定義了一組操作,無論使用的是什麼編譯器或 OS,這些操作都必須存在。
在 第一章 中已經提到,input 和 output 是特殊的程式引數。如果您在程式引數列表中列出它們,則可以使用這些識別符號來寫入和讀取終端,即您正在使用的 CLI。
事實上,input 和 output 是變數。它們的型別是 text。我們稱具有型別為 text 的變數為文字檔案。
文字檔案的 資料 由行組成。行是(可能為空的)字元序列(例如字母、數字、空格或標點符號),直到並且包括一個終止的“換行符”。
一個檔案 - 通常 - 具有以下屬性
- 它可以與外部實體關聯。外部意味著“在”您的程式“之外”。一個合適的實體可以是,例如,您的控制檯視窗、一個裝置(如您的鍵盤)或一個駐留在您的檔案系統中的檔案。
- 如果一個檔案與一個外部實體關聯,則它被認為是繫結的。
- 一個檔案有一個模式。每個檔案可以處於生成或檢查模式,沒有或兩者都有。如果一個檔案同時處於生成和檢查模式,這也可以稱為更新模式。 [fn 1]
- 每個檔案都有一個緩衝區。這個緩衝區是用於寫入或讀取資料的臨時儲存,實際上是另一個變數。由於計算機上 I/O 的工作方式,存在此緩衝區變數。
所有這些資訊都隱式提供給您,您無需關心它。您可以以預定義的方式查詢和更改某些資訊。
為了成功使用檔案,您只需要記住,一個檔案具有一個模式。文字檔案 input 和 output,一旦它們在程式引數列表中列出,就分別處於檢查和生成模式。您只能從處於檢查模式的檔案中讀取資料。並且只能寫入資料到處於生成模式的檔案中。
請注意,由於其特殊性質,input 和 output 的模式不能更改。
Pascal 定義了以下例程來讀取和寫入檔案
get,put,read/readLn,以及write/writeLn。
例程 readLn 和 writeLn 只能與文字檔案一起使用,而所有其他例程都適用於任何型別的檔案。在接下來的部分中,我們將重點介紹 read 和 write。這些例程建立在“低階” get 和 put 之上。在 “檔案” 章中,我們將對其進行研究。
讓我們看一個簡單的程式
program writeDemo(output);
var
x: integer;
begin
x := 10;
writeLn(output, x:20);
end.
複製該程式,看看它做了什麼。
首先,我們將學習一個新的語句,賦值。冒號等號 (:=) 讀作“變成”。在 x := 10 這行中,變數的值變成十。在左側,您寫入一個變數名。在右側,您放置一個值。該值必須對變數的型別有效。例如,您不能將 'Hello world!' 賦值給變數 x,因為它不是一個有效的 integer,即 x 的型別。
write/writeLn 的強大之處在於 - 對於文字檔案 - 它會將引數轉換為人類可讀的格式。在現代計算機中,十的 integer 值以特定的二進位制形式儲存。 00001010 是設定的位 (1) 和未設定的位 (0) 的視覺化表示,用於儲存“十”。然而,儘管是二進位制儲存,但您在螢幕上看到的字元是 10。這種從零和一到人類可讀表示(字元序列“10”)的轉換是自動完成的。
如果 write/writeLn 的目標是一個文字檔案,則所有引數都將轉換為人類可讀的格式,前提是這種轉換是必要的並且有意義的。 |
此外,在引數 x 之後是 :20。正如您可能已經注意到的,當您執行程式時,十的值右對齊,使 0 出現在 10 中,出現在第 20 列(從左邊緣開始的位置)。
:20 是一個 _格式說明符_。它確保給定引數具有 _至少_ 這麼多字元的寬度,並且它可以使用空格填充左側缺少的“寬度”。
在 write / writeLn 呼叫中的格式說明符只能在需要人類可讀表示的地方指定,換句話說,如果目標是文字檔案。 |
讀取資料
[edit | edit source]看看這個程式
program iceCream(input, output);
var
response: char;
begin
writeLn('Do you like ice cream?');
writeLn('Type “y” for “yes” (“Yummy!”) and “n” for “no”.');
writeLn('Confirm your selection by hitting Enter.');
readLn(input, response);
if response = 'y' then
begin
writeLn('Awesome!');
end;
end.
需求
[edit | edit source]傳遞給 read / readLn 的所有引數都必須是變數。第一個引數,即 _源_,必須是當前處於檢查模式的檔案變數。我們透過將 input 放入程式引數列表來確保這一點。如果源引數是 input,則允許您省略它,因此 readLn(response) 等效於 readLn(input, response)。
如果源是文字檔案,您只能為具有資料型別 char、integer、real 或“字串型別”的變數讀取值。其他與這些型別不相容的變數無法從文字檔案中讀取。(“相容”一詞將在後面解釋。) |
分支
[edit | edit source]我們將下一章詳細介紹的一種新的語言結構是 if - then 分支。僅當 response 等於字元值 'y' 時,才會執行 then 之後由 begin 和 end; 包圍的程式碼。否則,我們很禮貌,不會表達我們強烈的不同意見。
任務
[edit | edit source]write 到 input 嗎?為什麼/它應該工作,或者不工作?write 到 input。文字檔案 input 處於 _檢查_ 模式,前提是它在程式引數列表中。這意味著你只能從這個文字檔案 read 資料,而不能 write。
read 到 _常量_ 嗎?read / readLn 的所有引數都_必須_是變數。常量,根據定義,在執行時不會改變其值。這意味著,使用者也不能為常量賦值。
program valentine 並利用你在本章中學習的知識對其進行改進:使心形圖(類似)居中。假設控制檯視窗寬度為 80 個字元,或任何合理的寬度。program valentine(output);
const
width = 49;
begin
writeLn(' #### #### ':width);
writeLn(' ######## ######## ':width);
writeLn('## #### ##':width);
writeLn('## # ##':width);
writeLn('## ILY ##':width);
writeLn(' ## sweetie ## ':width);
writeLn(' ### ### ':width);
writeLn(' ### ### ':width);
writeLn(' ### ### ':width);
writeLn(' ### ':width);
writeLn(' # ':width);
end.
string 文字比 width 短(否則它不再像心形圖),那麼字串文字在_左側_可以更短。program valentine(output);
const
width = 49;
begin
writeLn( '#### #### ':width);
writeLn( '######## ######## ':width);
writeLn('## #### ##':width);
writeLn('## # ##':width);
writeLn('## ILY ##':width);
writeLn( '## sweetie ## ':width);
writeLn( '### ### ':width);
writeLn( '### ### ':width);
writeLn( '### ### ':width);
writeLn( '### ':width);
writeLn( '# ':width);
end.
o--------------------------------------o
| |
| |
| |
| |
o--------------------------------------o
''。它是兩個連在一起的直打字機撇號。你可以在你的解決方案中使用它。program box(output);
const
space = 38;
begin
writeLn('o--------------------------------------o');
writeLn('|', '':space, '|');
writeLn('|', '':space, '|');
writeLn('|', '':space, '|');
writeLn('|', '':space, '|');
writeLn('o--------------------------------------o');
end.
'':space 將生成 38 個空格(即常量 space 的值)。如果您真的聰明,您會注意到框的頂部和底部邊緣是_相同的_文字兩次。我們可以進一步縮短我們的程式program box(output);
const
space = 38;
topAndBottomEdge = 'o--------------------------------------o';
begin
writeLn(topAndBottomEdge);
writeLn('|', '':space, '|');
writeLn('|', '':space, '|');
writeLn('|', '':space, '|');
writeLn('|', '':space, '|');
writeLn(topAndBottomEdge);
end.
筆記
- ↑ “更新”模式僅在擴充套件 Pascal (ISO 標準 10206) 中可用。在標準(未擴充套件)Pascal(在 ISO 標準 7185 中規定)中,檔案可以處於檢查或生成模式,或者兩者都不處於。