程式扎記: [ Ruby Gossip ] Basic : 基本指令與觀念 - 基本輸入輸出

標籤

2014年10月2日 星期四

[ Ruby Gossip ] Basic : 基本指令與觀念 - 基本輸入輸出

Source From Here 
Preface 
如果要取得使用者的輸入,可以使用 ARGV, 使用者輸入的命令列引數,會收集為字串陣列並給 ARGV 參考。例如: 
- hello.rb 
  1. print "Hello, ", ARGV[0], "\n"  
如下執行指令載入指令稿直譯並執行: 
# ruby hello.rb john
Hello, john

上面這個範例可以更簡潔地寫為以下: 
  1. puts "Hello, #{ARGV[0]}"  
如果字串中包括 #{},括號中若指定了某個變數名稱,則直譯器會嘗試取得變數值後與字串結合。預設輸出會使用標準輸出STDOUT,如果想使用標準錯誤輸出,可以指定 STDERR。例如: 
  1. STDERR.print "Hello, #{ARGV[0]}"  
Basic I/O 
在程式執行的過程中,可以使用 gets 方法取得使用者的輸入,使用者輸入文字後按下 Enter,gets 會以字串傳回使用者的輸入,取得的字串會包括換行字元。例如: 
- hello2.rb 
  1. print "Input your name: "  
  2. name = gets  
  3. puts "Hello, #{name}!"  
如下執行指令載入指令稿直譯並執行: 
# rb hello2.rb
Input your name: john
Hello, john
!

注意最後一個行才出現!,這是因為 name 變數參考的字串,最後包括空白字元。如果想裁剪掉字串前後空白字元,像是換行字元,可以使用字串物件的 chomp 方法。例如: 
- hello3.rb 
  1. print "Input your name: "  
  2. name = gets.chomp  
  3. puts "Hello, #{name}!"  
執行結果如下,! 會緊接在同一行後,這是因為 name 變數參考的字串前後空白已被 chomp 裁掉: 
# rb hello3.rb
Input your name: john
Hello, john!

到目前為止,輸出都是使用 print 或 puts 方法,print 方法可以使用逗號區隔想輸出的文字,如第一個範例所示,puts 也可以,不過要注意,每個文字都會被換行。例如: 
  1. puts "This ""is ""a ""test""!"  
執行結果如下: 
This
is
a
test
!

如果要格式化輸出,可以使用 printf 方法。例如: 
>> printf("%d %.2f %s\n", 1, 99.3, "John")
1 99.30 John
=> nil

格式化輸出時,所使用的 %d、%f、%s 等與C語言類似,如果只是要格式化字串,則可以使用 sprintf 方法。例如: 
>> x = sprintf "%d %.2f %s", 1, 99.3, "John"
=> "1 99.30 John"
>> puts x
1 99.30 John
=> nil

格式化字串另一個簡便的方式,是透過 % 與陣列,例如: 
>> x = "%d %.02f %s" % [1, 99.3, "John"]
=> "1 99.30 John"

如果要將使用者的輸入字串轉換為整數、浮點等型態,可以使用 to_ito_f 方法。例如: 
>> "1".to_i
=> 1
>> "3.14".to_f
=> 3.14
>> "3.14".to_f + 123
=> 126.14

to_i、to_f 方法比較寬鬆,如果字串後段混有非數字部份,只會對數字部份予以剖析,如果不想要這個結果,可以使用 Integer 或 Float。例如: 
 

gets 方法是從標準輸入STDIN取得字串,如果想要讀取檔案,可以使用 File.read 方法。例如: 
  1. print "File name: "  
  2. name = gets.chomp  
  3. content = File.read(name)  
  4. puts content  
File.read 會一次讀取檔案所有內容,如果想要逐行讀取檔案內容,可以使用 open 方法。例如: 
  1. print "File name: "  
  2. name = gets.chomp  
  3. file = open(name, "r") # "r" 表示檔案供讀取使用  
  4. while line = file.gets  
  5.     print line  
  6. end  
  7. file.close  
gets 若讀到檔案結束,會傳回nil,這在布林判斷時會作為不成立,因此離開迴圈,在不使用檔案時可以使用 close 將檔案關閉以節省資源。另一個方式是使用區塊方式撰寫讀取邏輯。例如: 
  1. print "File name: "  
  2. name = gets.chomp  
  3. file = open(name, "r")  
  4. file.each do |line|  
  5.     print line  
  6. end  
  7. file.close  
open 之後傳回的物件,會有 each 方法,會將讀入的每一行設定給 |line| 中的line,open 本身也有區塊式寫法。例如: 
  1. print "File name: "  
  2. name = gets.chomp  
  3. open(name, "r"do |file|  
  4.     file.each do |line|  
  5.         print line  
  6.     end  
  7. end  
open 之後傳回的物件,會指定給 |file| 中的 file 參考,執行完區塊後會自動關閉檔案。 

如果要寫資料至檔案,則在使用 open 方法時,指定模式為 "w",並使用 print、puts 等方法進行資料寫入。例如: 
  1. print "File name: "  
  2. name = gets.chomp  
  3. open(name, "w"do |file|  
  4.     file.print "test"  
  5. end  
如果要以位元組方式讀入檔案,可以使用File實例的each_byte讀入位元組資料,如果要寫出位元組資料至檔案,可以使用File物件的print方法,將包括位元組內容的字串寫出。例如: 
  1. print "Src: "  
  2. src = gets.chomp  
  3. print "Dest: "  
  4. dest = gets.chomp  
  5. open(src, "rb"do |r_file|  
  6.     open(dest, "wb"do |w_file|  
  7.         r_file.each_byte do |byte|  
  8.             w_file.print([byte].pack("c*"))  
  9.         end  
  10.     end  
  11. end  
其中 b 指定用二進位方式開檔,pack 是 Array 實例的方法,指定 "c*" 表示將位元組資料包裝為字串(ASCII-8BIT)。如果需要更低階的操作,可以使用繼承自 IO 物件的 sysread 與 syswrite 方法。 

有關於不同編碼的檔案讀寫,則可以參考 關於編碼

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!