2014-05-13 45 views
0

我試圖用一個變量來指定在printf的方法寬度像這樣:如何使用變量來指定ruby的printf方法中的寬度?

puts "MAXES #{last_name_max} #{first_name_max} #{email_address_max} #{zipcode_max} #{city_max} #{state_max} #{street_max} #{homephone_max}" 
printf "%-#{last_name_max}s %-#{first_name_max}s %-#{email_address_max}s %-#{zipcode_max}s %-#{city_max}s %-#{state_max}s %-#{street_max}s %-#{homephone_max}s\n", 'LAST NAME', 'FIRST NAME', 'EMAIL', 'ZIPCODE', 'CITY', 'STATE', 'ADDRESS', 'PHONE' 
queue.each do |attendee| 
    printf "%-#{last_name_max}s %-#{first_name_max}s %-#{email_address_max}s %-#{zipcode_max}s %-#{city_max}s %-#{state_max}s %-#{street_max}s %-#{homephone_max}s\n", attendee[:last_name], attendee[:first_name], attendee[:email_address], attendee[:zipcode], attendee[:city], attendee[:state], attendee[:street], attendee[:homephone] 
end 

我一直在使用Google周圍,並與IRB玩,我想不出有什麼不對。這是輸出我得到:

Enter command: queue print 
MAXES 7 6 33 5 11 2 18 12 
LAST NAME FIRST NAME EMAIL        ZIPCODE CITY  STATE ADDRESS   PHONE  
Hasegan Audrey [email protected]  95667 Placerville CA 1570 Old Ranch Rd. 530-919-3000 
Zielke Eli [email protected] 92037 La Jolla CA 3024 Cranbrook Ct 858 405 3000 
Tippit Meggie [email protected]  94611 Piedmont CA 28 Olive Ave.  510 282 4000 
Enter command: q 

在IRB,printf("%-#{width}s", "ad")的作品,所以我認爲你可以在printf插值變量。我打印出前面使用的變量,因此它們應該是正確的。而當我使用數字而不是變量 - printf "%-20s %-20s... - 它的工作原理。我不知道還有什麼可能是錯的。

這是我的全碼:。

require 'CSV' 

puts 'Welcome to Event Reporter!' 
print 'Enter command: ' 
command = gets.chomp 

def clean(attribute, type) 
    if (type == 'regdate') 
    elsif (type == 'first_name') 
    elsif (type == 'last_name') 
    elsif (type == 'email_address') 
    elsif (type == 'homephone') 
     homephone = attribute 
     homephone = homephone.to_s.gsub(/\D/, '') 
     if (homephone.length < 10) 
      homephone = '0000000000' 
     elsif (homephone.length == 11) 
      if (homephone[0] == '1') 
       homephone[0] = '' 
      else 
       homephone = '0000000000' 
      end 
     elsif (homephone.length > 11) 
      homephone = '0000000000' 
     end 
     return homephone 
    elsif (type == 'street') 
    elsif (type == 'city') 
    elsif (type == 'state') 
    elsif (type == 'zipcode') 
     zipcode = attribute.to_s.rjust(5, "0")[0..4] 
     return zipcode 
    end 
    return attribute 
end 

queue = [] 
while (command != 'q') do 
    command = command.split 
    if (command[0] == 'load') 
     command[1] ? filename = command[1] : filename = 'event_attendees.csv' 
     attendees = CSV.open filename, headers: true, header_converters: :symbol 
     puts "Loaded #{filename}" 
    elsif (command[0] == 'find') 
     attribute = command[1] 
     criteria = command[2] 
     attendees.rewind 
     attendees.each do |attendee| 
      attendee_attribute = clean(attendee[attribute.to_sym], attribute) 
      queue << attendee if criteria.to_s.downcase.strip == attendee_attribute.to_s.downcase.strip 
     end 
    elsif (command[0] == 'queue') 
     if command[1] == 'count' 
      puts "Count: #{queue.length}" 
     elsif command[1] == 'clear' 
      queue = [] 
      puts 'Queue cleared.' 
     elsif (command[1] == 'print') 
      queue.to_a.sort_by! {|obj| obj[command[3]]} if command[2] == 'by' 
      last_name_max, first_name_max, email_address_max, zipcode_max, city_max, state_max, street_max, homephone_max = 0, 0, 0, 0, 0, 0, 0, 0 
      queue.each do |attendee| 
       last_name_max = attendee[:last_name].length if attendee[:last_name].length > last_name_max.to_i 
       first_name_max = attendee[:first_name].length if attendee[:first_name].length > first_name_max.to_i 
       email_address_max = attendee[:email_address].length if attendee[:email_address].length > email_address_max.to_i 
       zipcode_max = attendee[:zipcode].length if attendee[:zipcode].length > zipcode_max.to_i 
       city_max = attendee[:city].length if attendee[:city].length > city_max.to_i 
       state_max = attendee[:state].length if attendee[:state].length > state_max.to_i 
       street_max = attendee[:street].length if attendee[:street].length > street_max.to_i 
       homephone_max = attendee[:homephone].length if attendee[:homephone].length > homephone_max.to_i 
      end 
      puts "MAXES #{last_name_max} #{first_name_max} #{email_address_max} #{zipcode_max} #{city_max} #{state_max} #{street_max} #{homephone_max}" 
      printf "%-#{last_name_max}s %-#{first_name_max}s %-#{email_address_max}s %-#{zipcode_max}s %-#{city_max}s %-#{state_max}s %-#{street_max}s %-#{homephone_max}s\n", 'LAST NAME', 'FIRST NAME', 'EMAIL', 'ZIPCODE', 'CITY', 'STATE', 'ADDRESS', 'PHONE' 
      queue.each do |attendee| 
       printf "%-#{last_name_max}s %-#{first_name_max}s %-#{email_address_max}s %-#{zipcode_max}s %-#{city_max}s %-#{state_max}s %-#{street_max}s %-#{homephone_max}s\n", attendee[:last_name], attendee[:first_name], attendee[:email_address], attendee[:zipcode], attendee[:city], attendee[:state], attendee[:street], attendee[:homephone] 
      end 
     elsif (command[1] == 'save') 
      output_file = CSV.open(command[3], 'w') 
      output_file << ['last_name', 'first_name', 'email_address', 'zipcode', 'city', 'state', 'street', 'homephone'] 
      queue.each do |attendee| 
       output_file << [attendee[:last_name], attendee[:first_name], attendee[:email_address], attendee[:zipcode], attendee[:city], attendee[:state], attendee[:street], attendee[:homephone]] 
      end 
     end 
    elsif (command[0] == 'help') 
     puts "load <filename.csv>\nqueue count\nqueue clear\nqueue print\nqueue print by <attribute>\nqueue save to <filename.csv>\nfind <attribute> <criteria>" if !command[1] 
     puts 'Loads <filename.csv> (event_attendees.csv if not specified)' if command[1] == 'load' 
     if (command[1] == 'queue') 
      puts 'The cumulative number of attendees who match the criteria searched for.' if command[2] == 'count' 
      puts 'Clears the queue of matched attendees.' if command[2] == 'clear' 
      puts 'Prints out a table of the matched attendees.' if command[2] == 'print' && !command[3] 
      puts 'Prints out a table of the matched attendees sorted by <attribute>' if command[2] == 'print' && command[3] == 'by' 
      puts 'Saves the queue to the file.' if command[2] == 'save' 
     end 
     puts 'Adds matches to the queue' if command[1] == 'find' 
    end 
    print 'Enter command: ' 
    command = gets.chomp 
end 
+0

閱讀:http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882 – alfasin

回答

1

當計算字段的最大長度,你沒算在頭

puts "MAXES #{last_name_max} #{first_name_max}" 
#=> 7 6 

"LAST NAME" => length 9 
"FIRST NAME" => length 10 

printf "%-#d"不會截斷輸出寬度如#中所述。前兩個字段溢出,並且以下字段按預期進一步移動。

+0

我將'* _max'變量初始化爲標題的長度,現在它可以工作。謝謝! –

+0

@AdamZerner有['String#ljust'](http://www.ruby-doc.org/core-2.1.2/String.html#method-i-ljust),'String#center','' String#rjust'方法,您可能會發現它有幫助。 –

相關問題