为什么我的"文本到二进制转换器"不适用于Ruby

时间:2016-02-04 02:21:02

标签: ruby binary converter

好的,所以我想学习二进制编写程序,所以我可以说,"我可以在15岁时用二进制编码"。我构建了这个程序,但每次都打印相同的错误值。

lowerCaseLetters = {
"a" => 01100001,
"b" => 01100010,
"c" => 01100011,
"d" => 01100100,
"e" => 01100101,
"f" => 01100110,
"g" => 01100111,
"h" => 01101000,
"i" => 01101001,
"j" => 01101010,
"k" => 01101011,
"l" => 01101100,
"m" => 01101101,
"n" => 01101110,
"o" => 01101111,
"p" => 01110000,
"q" => 01110001,
"r" => 01110010,
"s" => 01110011,
"t" => 01110100,
"u" => 01110101,
"v" => 01110110,
"w" => 01110111,
"x" => 01111000,
"y" => 01111001,
"z" => 01111010
}

puts "Type your message in English please, and \n -I the program will translate it into BINARY!!-"
userMessage = gets.chomp

puts "Your message in English says: \n >#{userMessage}"
lowerCaseLetters.each {
    |letter, number|
    print "#{number},"
}

因此,当我运行此程序时,无论我键入什么,程序都会输出这些值。即使我输入一个值,也就是6个值(这是我迄今为止最高的...... giggity)

这是终端的两个例子。 例1:

Type your message in English please, and 
 -I the program will translate it into BINARY!!-
j
Your message in English says: 
 >j
294913,294920,294921,294976,294977,294984,294985,295424,295425,295432,295433,295488,295489,295496,295497,299008,299009,299016,299017,299072,299073,299080,299081,299520,299521,299528,

示例2:

Type your message in English please, and 
 -I the program will translate it into BINARY!!-
jeebs
Your message in English says: 
 >jeebs
294913,294920,294921,294976,294977,294984,294985,295424,295425,295432,295433,295488,295489,295496,295497,299008,299009,299016,299017,299072,299073,299080,299081,299520,299521,299528,

我在哪里以及为什么会出现语法错误?谢谢!

3 个答案:

答案 0 :(得分:1)

0开头的数字保留用于八进制表示,因此请尝试将其作为解决方法:

lowerCaseLetters = { "a" => '01100001', "b" => '01100010',
  "c" => '01100011', "d" => '01100100', "e" => '01100101',
  "f" => '01100110', "g" => '01100111', "h" => '01101000',
  "i" => '01101001', "j" => '01101010', "k" => '01101011',
  "l" => '01101100', "m" => '01101101', "n" => '01101110',
  "o" => '01101111', "p" => '01110000', "q" => '01110001',
  "r" => '01110010', "s" => '01110011', "t" => '01110100',
  "u" => '01110101', "v" => '01110110', "w" => '01110111',
  "x" => '01111000', "y" => '01111001', "z" => '01111010'
}

puts "Type your message in English please,"
puts "and I the program will translate it into BINARY!!-"

userMessage = gets.chomp.split('')

puts "Your message in English says: "
userMessage.each {|letter| print lowerCaseLetters[letter] + " " }
puts

所以输入'ab'会返回:01100001 01100010

答案 1 :(得分:0)

我建议您查看本教程,将字符串转换为二进制文件。

http://blog.anidear.com/2011/11/convert-string-to-binary-in-ruby.html

Ruby内置了功能。 使用Ruby内置Base64编码器/解码器的奖励信息,供您将来参考。

您还可以查看此字符串到二进制的在线转换器以查看结果。

http://binary.online-toolz.com/tools/text-binary-convertor.php

http://codebeautify.org/binary-string-converter

希望它有所帮助!

答案 2 :(得分:0)

  

我在哪里以及为什么会出现语法错误?

好消息是你没有syntax errors。坏消息是你确实有逻辑错误,而且调试起来要困难得多。

如何调试Ruby

最简单的方法是IRB,这是一个允许您以交互方式执行Ruby表达式的工具(这称为REPL)。您可以在终端窗口中键入irb来启动它:

$ irb
irb(main):001:0>

输入Ruby表达式,IRB将显示其结果:

irb(main):001:0> 1 + 2
#=> 3
irb(main):002:0>

二进制数

现在,让我们检查一下你的二进制数:

irb(main):002:0> 01100001
#=> 294913

同样奇怪的输出。发生了什么事?

Ruby允许您使用特殊前缀在不同的bases中编写数字。 number literals的文档提供了一些见解:

  

您可以使用特殊前缀以十进制,十六进制,八进制或二进制格式写入数字。对于十进制数字,使用前缀0d,对于十六进制数字,使用前缀0x,对于八进制数字,使用前缀00o,对于二进制数字使用前缀0b

您的号码以0开头,因此01100001被解释为八进制号码:

<强> 1100001 <子> 8
= 1 ×8 6 + 1 ×8 5 + 0 ×8 4 + 0 ×8 3 + 0 ×8 2 + 0 ×8 1 + 1 ×8 0
= 262,144 + 32,768 + 0 + 0 + 0 + 0 + 1
= 294,913

要输入二进制号码,您必须使用0b前缀:(我将号码分配给名为number的变量,以便我们可以参考稍后)

irb(main):003:0> number = 0b01100001
#=> 97

<强> 01100001 <子> 2
= 0 ×2 7 + 1 ×2 6 + 1 ×2 5 + 0 ×2 4 + 0 ×2 3 + 0 ×2 2 + 0 ×2 1 + 1 ×2 0
= 0 + 64 + 32 + 0 + 0 + 0 + 0 + 1
= 97

格式化数字

但是为什么Ruby输出97而不是01100001?这是因为在打印对象时,Ruby会调用对象的to_s方法。我们的号码是Fixnum

irb(main):004:0> number.class
#=> Fixnum

Fixnum#to_s的文档显示该方法采用可选参数base,默认值为10

  

<强> to_s(碱= 10)

     

返回包含fix基数base(2到36之间)表示的字符串。

让我们试试2

irb(main):005:0> number.to_s(2)
#=> "1100001"

看起来不错,但领先0已经不见了。为了得到它,我们可以使用一个更强大的方法sprintf,它允许我们精确地指定格式:

irb(main):006:0> sprintf('%08b', number)
#=> "01100001"

%08b表示:

  • %启动格式序列
  • 0用零填充
  • 8宽度为8位数
  • b二进制数

适用于您的计划

字母哈希必须写成:(在Ruby中我们使用snake_case作为变量名)

lower_case_letters = {
  "a" => 0b01100001,
  "b" => 0b01100010,
  "c" => 0b01100011,
  # ...
  "z" => 0b01111010
}

可以通过以下方式收集输出:(仅修复变量名称)

user_message = gets.chomp

但是为了打印user_message中每个字符的哈希值,你必须遍历字符(而不是哈希)。相应的方法称为String#each_char

user_message.each_char do |character|
  number = lower_case_letters[character]
  printf('%08b', number)
end

我在上面的代码中使用printf。它相当于print sprintf(...)

一点点重构

String有另一种方法each_byte。它的工作方式与each_char类似,但不是将每个字符传递给块,而是传递每个字节:

user_message.each_byte { |byte| printf('%08b', byte) }