- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is it possible to initialize a character array using hex values for the bytes?
using character(10) :: ch =
ie. it may contain non printable bytes such as 0x0D, etc
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ie I'm trying to initialize all the bytes of a long character string using a DATA statement or in the declaration of the character variable.
something like:
character(10) :: ch
data ch(1:10) / Z'41', Z'42', Z'4A', Z'45', Z'47', Z'4F', Z'0D', Z'42', Z'42', Z'45' /
which obviously doesn't work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A little tedious but you can have something like:
character(len=3), parameter :: gch=achar(int(Z'41'))//achar(int(Z'42'))//achar(int(Z'43'))
The Fortran standard is quite restrictive on BOZ literal constants and you can only use for integer assignment. The above is standard conforming Fortran 2008 (/stand:f08)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, this also works:
data ch(1:1) / Z'91'/, ch(2:2) / Z'd5'/, ch(3:3) /Z'12'/, ch(4:4) /Z'00'/
But looks a bit messy as well.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
warning #6473: Fortran 2008 does not allow boz constant in this context. [CH]
warning #6953: Fortran 2008 does not allow an 8-bit integer ASCII constant to be stored in a CHARACTER constant. [CH]
Your example will work in ifort but is not standard fortran
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would do it like this:
character(10) :: ch = 'ABJEGO' // CHAR(13) // 'BBE'
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No that would not work for me. I have a 64 byte character string which I want to initialize to a defined set of 64 bytes, which can be anything from 00 to FF. This is what I'm doing now:
DATA KEY1 (01:01) /Z'48'/, KEY1 (02:02) /Z'35'/, KEY1 (03:03) /Z'3e'/, KEY1 (04:04) /Z'44'/, & KEY1 (05:05) /Z'2f'/, KEY1 (06:06) /Z'08'/, KEY1 (07:07) /Z'4d'/, KEY1 (08:08) /Z'6b'/, &
etc. As I mentioned something like this would be better:
character(10) :: ch
data ch(1:10) / Z'41', Z'42', Z'4A', Z'45', Z'47', Z'4F', Z'0D', Z'42', Z'42', Z'45' /
Adrian
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had success with this:
program P implicit none character(8) :: key1 = transfer(char(int([ & Z'48',Z'35',Z'3E',Z'44',Z'2F',Z'08',Z'4d',Z'6B' & ])),repeat('A',8)) integer i write(*,'(*(Z0.2:1x))') (key1(i:i),i=1,len(key1)) end program P
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually it's a bit of a bug in both ifort and gfortran that they accept the syntax in Quote #8 without warning with standards checking enforced. To see what I mean, what do you think the output of this should be?
write(*,*) real([Z'3F800000',Z'40000000',Z'40400000',Z'40800000']) end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I feel bad for some reason.
INTEGER, PARAMETER :: char_values(8) = [ & INT(Z'48'), INT(Z'35'), INT(Z'3E'), INT(Z'44'), & INT(Z'2F'), INT(Z'08'), INT(Z'4D'), INT(Z'6B') ] CHARACTER :: dummy(SIZE(char_values)) = ACHAR(char_values) CHARACTER(SIZE(char_values)) :: ch EQUIVALENCE(dummy, ch) INTEGER :: i PRINT "(*(Z2.2,:,','))", (IACHAR(ch(i:i)), i=1, LEN(ch)) END
A `JOIN` intrinsic (or whatever) to convert a character array into a scalar would be nice.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Repeat Offender wrote:
...To see what I mean, what do you think the output of this should be?
write(*,*) real([Z'3F800000',Z'40000000',Z'40400000',Z'40800000']) end
The output would not be as interesting as "1, 2, 3, 4". To obtain that, you would have to use an intrinsic that is part of the signature of a well-known personality of C.L.F.: TRANSFER() instead of REAL().
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
RO, thanks for the comment about the standards warning - I've passed that on to the developers as issue DPD200359636. As you point out, that line isn't the same as:
write(*,*) [real(Z'3F800000'),real(Z'40000000'),real(Z'40400000'),real(Z'40800000')]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TRANSFER has a problem in that what 'loose' BOZ means varies by compiler. Thus replacing REAL with TRANSFER is OK on ifort, but in gfortran you get a size-16 array. You would need TRANSFER(INT or even TRANSFER(REAL to provide the appropriate bit size context for TRANSFER to be effective, but that would make TRANSFER redundant.
JOIN would never get off the ground because there is a question of whether you want it to work like MIN and MAX or like SUM, PRODUCT, ANY, ALL, PARITY, IANY, IALL, IPARITY, MINVAL, MAXVAL, MINLOC, and MAXLOC.
But I can't see why CHAR and ACHAR can't directly take BOZ the way INT, REAL, CMPLX, and DBLE do. After all, ASCII is generally presented in hex form.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tend to agree - CHAR and ACHAR should be treated the same as INT for this purpose. I have made a note to suggest this for a future standard.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
I tend to agree - CHAR and ACHAR should be treated the same as INT for this purpose. I have made a note to suggest this for a future standard.
That would be nice, I have had to resort to the shenanigans at #3 to be conforming which is rather tedious and unnecessary...
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page