[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Trouble using string.tr

Todd Burch

5/10/2007 3:02:00 PM

I've coded up EBCDIC to ASCII translate strings. Everything is working
fine, except for the greater than symbol. (In EBCDIC, X'6E').

What is happening is that whenever a > is in the input string, it gets
translated with the character immediately following my '>' in the
TO_STRING.

I've spent a lot of time making sure my characters in the FROM_STRING
and TO_STRING are in the proper order.

I've tried escaping it to no avail. I looked in the doc index for
special notes about it, and did not see any. A Google search found
nothing either.

Any ideas? I can provide the code if needed.

Todd

--
Posted via http://www.ruby-....

21 Answers

Alex LeDonne

5/10/2007 3:12:00 PM

0

On 5/10/07, Todd Burch <promos@burchwoodusa.com> wrote:
> I've coded up EBCDIC to ASCII translate strings. Everything is working
> fine, except for the greater than symbol. (In EBCDIC, X'6E').
>
> What is happening is that whenever a > is in the input string, it gets
> translated with the character immediately following my '>' in the
> TO_STRING.
>
> I've spent a lot of time making sure my characters in the FROM_STRING
> and TO_STRING are in the proper order.
>
> I've tried escaping it to no avail. I looked in the doc index for
> special notes about it, and did not see any. A Google search found
> nothing either.
>
> Any ideas? I can provide the code if needed.
>
> Todd
>

Please do post the code.

-A

Robert Klemme

5/10/2007 3:13:00 PM

0

On 10.05.2007 17:01, Todd Burch wrote:
> I've coded up EBCDIC to ASCII translate strings. Everything is working
> fine, except for the greater than symbol. (In EBCDIC, X'6E').
>
> What is happening is that whenever a > is in the input string, it gets
> translated with the character immediately following my '>' in the
> TO_STRING.
>
> I've spent a lot of time making sure my characters in the FROM_STRING
> and TO_STRING are in the proper order.
>
> I've tried escaping it to no avail. I looked in the doc index for
> special notes about it, and did not see any. A Google search found
> nothing either.
>
> Any ideas? I can provide the code if needed.

Yes, that would be good.

robert

Todd Burch

5/10/2007 3:21:00 PM

0

Here are the two translate strings. Need more code? Thanks y'all.

$ebcdic_chars = 0x40.chr ; # blank
###$ebcdic_chars += 0xFF.chr ; # unprintable
###$ebcdic_chars += 0x00.chr ; # unprintable

$ebcdic_chars += 0XC1.chr + 0xC2.chr + 0xC3.chr + 0xC4.chr + 0xC5.chr +
0xC6.chr + 0xC7.chr + 0xC8.chr + 0xC9.chr ; # A-I
$ebcdic_chars += 0XD1.chr + 0xD2.chr + 0xD3.chr + 0xD4.chr + 0xD5.chr +
0xD6.chr + 0xD7.chr + 0xD8.chr + 0xD9.chr ; # J-R
$ebcdic_chars += 0xE2.chr + 0xE3.chr + 0xE4.chr + 0xE5.chr +
0xE6.chr + 0xE7.chr + 0xE8.chr + 0xE9.chr ; # S-Z
$ebcdic_chars += 0X81.chr + 0x82.chr + 0x83.chr + 0x84.chr + 0x85.chr +
0x86.chr + 0x87.chr + 0x88.chr + 0x89.chr ; # a-i
$ebcdic_chars += 0X91.chr + 0x92.chr + 0x93.chr + 0x94.chr + 0x95.chr +
0x96.chr + 0x97.chr + 0x98.chr + 0x99.chr ; # j-r
$ebcdic_chars += 0xA2.chr + 0xA3.chr + 0xA4.chr + 0xA5.chr +
0xA6.chr + 0xA7.chr + 0xA8.chr + 0xA9.chr ; # s-z


$ebcdic_chars += 0x4B.chr ; # .
$ebcdic_chars += 0x4C.chr ; # <
$ebcdic_chars += 0x4D.chr ; # (
$ebcdic_chars += 0x4E.chr ; # +
$ebcdic_chars += 0x4F.chr ; # |
$ebcdic_chars += 0x50.chr ; # &

$ebcdic_chars += 0x5A.chr ; # !
$ebcdic_chars += 0x5B.chr ; # $
$ebcdic_chars += 0x5C.chr ; # *
$ebcdic_chars += 0x5D.chr ; # )
$ebcdic_chars += 0x5E.chr ; # ;
$ebcdic_chars += 0x5F.chr ; # ^
$ebcdic_chars += 0x60.chr ; # -
$ebcdic_chars += 0x61.chr ; # /

$ebcdic_chars += 0x6B.chr ; # ,
$ebcdic_chars += 0x6C.chr ; # %
$ebcdic_chars += 0x6D.chr ; # _
$ebcdic_chars += 0x6E.chr ; # >
$ebcdic_chars += 0x6F.chr ; # ?
$ebcdic_chars += 0X79.chr ; # `
$ebcdic_chars += 0x7A.chr ; # :
$ebcdic_chars += 0x7B.chr ; # #
$ebcdic_chars += 0x7C.chr ; # @
$ebcdic_chars += 0x7D.chr ; # '
$ebcdic_chars += 0x7E.chr ; # =
$ebcdic_chars += 0x7F.chr ; # "
$ebcdic_chars += 0xBA.chr ; # [
$ebcdic_chars += 0xBB.chr ; # ]
$ebcdic_chars += 0xC0.chr ; # {
$ebcdic_chars += 0xD0.chr ; # }
$ebcdic_chars += 0xE0.chr ; #

$ascii_chars = " " ; # blank
###$ascii_chars += " " ; # make ebcdic 0XFF into a blank
###$ascii_chars += ' ' ; # make ebcdic 0X00 into a blank
$ascii_chars += ('A'..'Z').to_a.to_s ; # A-Z
$ascii_chars += ('a'..'z').to_a.to_s ; # a-z

$ascii_chars += '.' ;
$ascii_chars += '<' ;
$ascii_chars += '(' ;
$ascii_chars += '+' ;
$ascii_chars += '|' ;
$ascii_chars += '&' ;

$ascii_chars += '!' ;
$ascii_chars += '$' ;
$ascii_chars += '*' ;
$ascii_chars += ')' ;
$ascii_chars += ';' ;
$ascii_chars += '^' ;
$ascii_chars += '-' ;
$ascii_chars += '/' ;

$ascii_chars += ',' ;
$ascii_chars += '%' ;
$ascii_chars += '_' ;
$ascii_chars += '\>' ;
$ascii_chars += '?' ;
$ascii_chars += '`' ;
$ascii_chars += ':' ;
$ascii_chars += '#' ;
$ascii_chars += '@' ;
$ascii_chars += '\'';
$ascii_chars += '=' ;
$ascii_chars += '"' ;
$ascii_chars += '[' ;
$ascii_chars += ']' ;
$ascii_chars += '{' ;
$ascii_chars += '}' ;
$ascii_chars += '\\' ; # escape char is special - must be doubled

$ebcdic_nums = 0xF0.chr + 0XF1.chr + 0xF2.chr + 0xF3.chr + 0xF4.chr +
0xF5.chr + 0xF6.chr + 0xF7.chr + 0xF8.chr + 0xF9.chr ;
$ascii_nums = "0123456789" ;

$ebcdic_chars += $ebcdic_nums ;
$ascii_chars += $ascii_nums ;


--
Posted via http://www.ruby-....

Todd Burch

5/10/2007 3:23:00 PM

0

Note, the version I'm showing has the backslash. It fails with or
without it. (and I'm not even certain that \> is even valid!!)

Todd

--
Posted via http://www.ruby-....

Robert Klemme

5/10/2007 3:35:00 PM

0

On 10.05.2007 17:23, Todd Burch wrote:
> Note, the version I'm showing has the backslash. It fails with or
> without it. (and I'm not even certain that \> is even valid!!)

>> '\>'
=> "\\>"
>> '>'
=> ">"

The backslash is wrong there.

A more robust way to code this would be to use a HashMap - at least to
initially associate ASCII with EBCDIC chars. So, I'd rather to

CHAR_MAP = {
0XC1 => ?A,
0xC2 => ?B,
# ...
}

Then you can do:

ebcdic, ascii = [CHAR_MAP.keys, CHAR_MAP.values].map do |set|
set.inject("") {|st, ch| st << ch}
end

Kind regards

robert

Rob Biedenharn

5/10/2007 3:37:00 PM

0

On May 10, 2007, at 11:01 AM, Todd Burch wrote:

> I've coded up EBCDIC to ASCII translate strings. Everything is
> working
> fine, except for the greater than symbol. (In EBCDIC, X'6E').
>
> What is happening is that whenever a > is in the input string, it gets
> translated with the character immediately following my '>' in the
> TO_STRING.
>
> I've spent a lot of time making sure my characters in the FROM_STRING
> and TO_STRING are in the proper order.
>
> I've tried escaping it to no avail. I looked in the doc index for
> special notes about it, and did not see any. A Google search found
> nothing either.
>
> Any ideas? I can provide the code if needed.
>
> Todd

where does the code X'5C' appear? (that's a \ in ASCII) Even in
single quotes, there are two special sequences:
irb(main):001:0> a='\\'
=> "\\"
irb(main):002:0> puts a
=> nil
irb(main):003:0> b='\''
=> "'"
irb(main):004:0> puts b
'
=> nil

(but please do show the code!)

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com



Todd Burch

5/10/2007 4:13:00 PM

0

I'll need to code up a smaller example than the 400+ lines I have right
now. I'll be able to do that soon. Thanks for the replies so far - I
need to sudy them.

Todd

--
Posted via http://www.ruby-....

Todd Burch

5/10/2007 4:40:00 PM

0

Here a whole program that illlustrates the error. I'm running under
Windows Ruby 1.8.5. (it's ugly and chopped up, but it works... er...
doesn't work... er... you know what I mean)

Todd


#
# Ruby program to convert a z/OS EBCDIC to ASCII.
#

class Record

#
# The Record.report_values() method used the Record Layout info and
parses a record at a time, building the output ASCII row.
#

def Record.report_values(edata) ; # ebcdic data

adata = edata.tr($ebcdic_chars, $ascii_chars) ; # ascii data
puts "ebcdic data = #{edata}" ;
puts ;
puts "ascii data = #{adata}" ;
puts ;
end ; # def report_values


#
# This Record.to_h() method converts a hex byte into a displayable,
human readable value. i.e. X'F5' to "F5".
#

def Record.to_h(str)
str.unpack('H64').to_s.upcase ;
end ;

#
# This method called to dump the data in hex format.
#

def Record.dump_area(data) ;

fsize = data.size ;
lines,last = fsize.divmod(32) # get # of full lines and figure the
remainder.
i = 0
while lines > 0
str = data[i..i+31]
hexdata = Record.to_h(str) # .unpack('H64').to_s.upcase
printf( "%08X %8s %8s %8s %8s %8s %8s %8s %8s %s\n",
i, hexdata[0..7], hexdata[8..15],
hexdata[16..23], hexdata[24..31],
hexdata[32..39], hexdata[40..47],
hexdata[48..55], hexdata[56..63],
str.tr("\000-\037\177-\377",'.'))
i += 32; lines -= 1
end

# Write out the partial line.

str = data[i..fsize]
line = sprintf("%08x ",i)
i.upto(fsize) {|x|
line << sprintf("%2s",data[x..x].unpack('H2').to_s.upcase)
if (((x+1)% 4)==0) then line << " " end
if (((x+1)%16)==0) then line << " " end
}
line << " "*(2+90-line.length)
line << sprintf("%s\n", str.tr("\000-\037\177-\377",'.'))
printf(line)
end ;

end ; # class Record. This is the end of all the method defintions for
class Record.


def doit(data) ;


#
# Now starts the translate table definitions. They are order-sensitive.
Do not change the order unless you have a real reason to.
#
# $ebcdic_chars (global variable) is the "from string" portion of the
translate process.
# $ascii_chars is the "to string" portion.
#
# $ebcdic_nums is the "from string" for converting from X'F0' through
X'F9' (0-9 ebcdic)
# $ascii_nums is the "to string" for converting to X'30' through
X'39' (0-9 ascii)
#

$ebcdic_chars = 0x40.chr ; # blank
###$ebcdic_chars += 0xFF.chr ; # unprintable
###$ebcdic_chars += 0x00.chr ; # unprintable

$ebcdic_chars += 0XC1.chr + 0xC2.chr + 0xC3.chr + 0xC4.chr + 0xC5.chr +
0xC6.chr + 0xC7.chr + 0xC8.chr + 0xC9.chr ; # A-I
$ebcdic_chars += 0XD1.chr + 0xD2.chr + 0xD3.chr + 0xD4.chr + 0xD5.chr +
0xD6.chr + 0xD7.chr + 0xD8.chr + 0xD9.chr ; # J-R
$ebcdic_chars += 0xE2.chr + 0xE3.chr + 0xE4.chr + 0xE5.chr +
0xE6.chr + 0xE7.chr + 0xE8.chr + 0xE9.chr ; # S-Z
$ebcdic_chars += 0X81.chr + 0x82.chr + 0x83.chr + 0x84.chr + 0x85.chr +
0x86.chr + 0x87.chr + 0x88.chr + 0x89.chr ; # a-i
$ebcdic_chars += 0X91.chr + 0x92.chr + 0x93.chr + 0x94.chr + 0x95.chr +
0x96.chr + 0x97.chr + 0x98.chr + 0x99.chr ; # j-r
$ebcdic_chars += 0xA2.chr + 0xA3.chr + 0xA4.chr + 0xA5.chr +
0xA6.chr + 0xA7.chr + 0xA8.chr + 0xA9.chr ; # s-z


$ebcdic_chars += 0x4B.chr ; # .
$ebcdic_chars += 0x4C.chr ; # <
$ebcdic_chars += 0x4D.chr ; # (
$ebcdic_chars += 0x4E.chr ; # +
$ebcdic_chars += 0x4F.chr ; # |
$ebcdic_chars += 0x50.chr ; # &

$ebcdic_chars += 0x5A.chr ; # !
$ebcdic_chars += 0x5B.chr ; # $
$ebcdic_chars += 0x5C.chr ; # *
$ebcdic_chars += 0x5D.chr ; # )
$ebcdic_chars += 0x5E.chr ; # ;
$ebcdic_chars += 0x5F.chr ; # ^
$ebcdic_chars += 0x60.chr ; # -
$ebcdic_chars += 0x61.chr ; # /

$ebcdic_chars += 0x6B.chr ; # ,
$ebcdic_chars += 0x6C.chr ; # %
$ebcdic_chars += 0x6D.chr ; # _
$ebcdic_chars += 0x6E.chr ; # >
$ebcdic_chars += 0x6F.chr ; # ?
$ebcdic_chars += 0X79.chr ; # `
$ebcdic_chars += 0x7A.chr ; # :
$ebcdic_chars += 0x7B.chr ; # #
$ebcdic_chars += 0x7C.chr ; # @
$ebcdic_chars += 0x7D.chr ; # '
$ebcdic_chars += 0x7E.chr ; # =
$ebcdic_chars += 0x7F.chr ; # "
$ebcdic_chars += 0xBA.chr ; # [
$ebcdic_chars += 0xBB.chr ; # ]
$ebcdic_chars += 0xC0.chr ; # {
$ebcdic_chars += 0xD0.chr ; # }
$ebcdic_chars += 0xE0.chr ; #

$ascii_chars = " " ; # blank
###$ascii_chars += " " ; # make ebcdic 0XFF into a blank
###$ascii_chars += ' ' ; # make ebcdic 0X00 into a blank
$ascii_chars += ('A'..'Z').to_a.to_s ; # A-Z
$ascii_chars += ('a'..'z').to_a.to_s ; # a-z

$ascii_chars += '.' ;
$ascii_chars += '<' ;
$ascii_chars += '(' ;
$ascii_chars += '+' ;
$ascii_chars += '|' ;
$ascii_chars += '&' ;

$ascii_chars += '!' ;
$ascii_chars += '$' ;
$ascii_chars += '*' ;
$ascii_chars += ')' ;
$ascii_chars += ';' ;
$ascii_chars += '^' ;
$ascii_chars += '-' ;
$ascii_chars += '/' ;

$ascii_chars += ',' ;
$ascii_chars += '%' ;
$ascii_chars += '_' ;
$ascii_chars += '>' ;
$ascii_chars += '?' ;
$ascii_chars += '`' ;
$ascii_chars += ':' ;
$ascii_chars += '#' ;
$ascii_chars += '@' ;
$ascii_chars += '\'';
$ascii_chars += '=' ;
$ascii_chars += '"' ;
$ascii_chars += '[' ;
$ascii_chars += ']' ;
$ascii_chars += '{' ;
$ascii_chars += '}' ;
$ascii_chars += '\\' ; # escape char is special - must be doubled

$ebcdic_nums = 0xF0.chr + 0XF1.chr + 0xF2.chr + 0xF3.chr + 0xF4.chr +
0xF5.chr + 0xF6.chr + 0xF7.chr + 0xF8.chr + 0xF9.chr ;
$ascii_nums = "0123456789" ;

$ebcdic_chars += $ebcdic_nums ;
$ascii_chars += $ascii_nums ;

# true if the record was
as expected, or false if not.
Record.report_values(data)

Record.dump_area( data ) ; # write offending record, in hex dump
format, to the INVALID_FORMAT file.

end ; # def doit()



instring = 0XC1.chr + 0xC2.chr + 0x6E.chr + 0xC1.chr + 0xC1.chr +
0x4C.chr + 0xC1.chr + 0xC3.chr ; # EBCDIC for "AB>AA<AC"

doit(instring) ; # run the program.


--
Posted via http://www.ruby-....

Todd Burch

5/10/2007 4:55:00 PM

0

Here's another twist.

If I set

instring = 0xF1.chr + 0xF2.chr + 0x4B.chr + 0xF3.chr + 0xF4.chr

which is ebcdic for "12.34", I get "45.67" in ascii. It looks like
something ( tr() maybe? ) is swallowing characters.

Todd

--
Posted via http://www.ruby-....

Todd Burch

5/10/2007 5:10:00 PM

0

Rob Biedenharn wrote:
>
> where does the code X'5C' appear? (that's a \ in ASCII)

In ebcdic, a 0X5C is an asterisk. In ebcdic, a 0XE0 is an backslash.
Both are in from_string.

Todd

--
Posted via http://www.ruby-....