Write array of radix-2 numeric strings to binary file in Ruby
I think you can just use Array#pack
and String#unpack
like the following code:
# Writing
a = ["010", "1111", "10", "10", "110", "1110", "001", "110", "000", "10", "011"]
File.open("out.cake", 'wb' ) do |output|
output.write [a.join].pack("B*")
end
# Reading
s = File.binread("out.cake")
bits = s.unpack("B*")[0] # "01011111010110111000111000010011"
I don't know your preferred format for the result of reading and I know the above method is inefficient. But anyway you can take "0" or "1" sequentially from the result of unpack
to traverse your Huffman tree.
Why Ruby does not read all bytes from a file
Already solved.
I was trying with different encodings, and I tried opening the source
file in binary mode, but It got another error because I forgot open the destination
file in binary mode too.
It read all bytes fine, and write fine too, opening both files in binary mode.
Here, my code:
destination = File("file2", "wb")
source = File.open("file1", "rb")
source.each_byte do |byte|
destination.print (byte).chr
end
destination.close
source.close
How to turn characters to bits in Ruby
You can use unpack
:
'hello'.unpack('B*')
#=> ["0110100001100101011011000110110001101111"]
# ^^^^^^^^
# 01101000 = h
Safe integer parsing in Ruby
Ruby has this functionality built in:
Integer('1001') # => 1001
Integer('1001 nights')
# ArgumentError: invalid value for Integer: "1001 nights"
As noted in answer by Joseph Pecoraro, you might want to watch for strings that are valid non-decimal numbers, such as those starting with 0x
for hex and 0b
for binary, and potentially more tricky numbers starting with zero that will be parsed as octal.
Ruby 1.9.2 added optional second argument for radix so above issue can be avoided:
Integer('23') # => 23
Integer('0x23') # => 35
Integer('023') # => 19
Integer('0x23', 10)
# => #<ArgumentError: invalid value for Integer: "0x23">
Integer('023', 10) # => 23
Is there a radix function in ruby?
The to_s method in Ruby integer classes has an optional parameter specifying the base, something like:
123456.to_s(16)
However, it only accepts values from 2 to 36 as the radix.
This snippet might be a good starting place if you want to write your own encoder. There's also a base62 Ruby Gem that adds methods for encoding and decoding in base62.
Why does `Integer('009')` not work, but `Float('009')` does?
Kernel#Integer interprets arguments starting with a leading 0
as octal. Because the octal number system ony uses digits 0-7
, a number containing a 9
is not defined. From the documentation:
If arg is a String, when base is omitted or equals zero, radix indicators (0, 0b, and 0x) are honored.
Kernel#Float, on the other hand, does not behave this way.
To convert "009"
to an integer in base 10 using Integer
, you need to pass an optional argument specifying the base:
Integer("009", 10)
Related Topics
Convert Ruby Source Code from Old Style to New Style Hash
Regex to Validate String Having Only Characters (Not Special Characters), Blank Spaces and Numbers
Ruby - Extracting the Unique Values Per Key from an Array of Hashes
Colorized Output Breaks Linewrapping with Readline
Script to Run Against Stdin If No Arg; Otherwise Input File =Argv[0]
Cannot Load Such File -- Rack/Handler/Puma
Extract All Urls Inside a String in Ruby
Generate Random String Based on Regex
How to Use Link_To to Link an Image and a Text
Irb: How to Start an Interactive Ruby Session with Pre-Loaded Classes
Detecting If This Is an Iframe Load or Direct
Ruby on Rails Country/State Select Enigma
Parse Large JSON Hash with Ruby-Yajl
What Are Some Good Role Authorization Solutions Used with Authlogic
Authlogic Perishable_Token Resets on Every Request
Convert Timestamp Timezone in Logstash for Output Index Name