Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

integer to character string.

JohnNichols
Valued Contributor III
1,747 Views

I am writing a string of characters to the bitmap format.  

The final problem is converting integer numbers to characters.  I have numbers in the range 0 to 1000, but you can only output one font character at a time.  SO I need to break up 100 into 1   0  0 and convert to characters. 

Why does the following routine require CA to be at least 12 characters to work?  Is it controlled by the maximum range of the 32 bit integer which is 12 numbers long? including the +-

 

 

 subroutine stringer(KVG)

    implicit none

    TYPE(stringRC) KVG
    character(11) CA

    integer num

    num = KVG%num
    if(num .lt. 10) then
        if(num .eq. 0) then
            KVG%flag = 1
            KVG%A = "0"
        elseif(num .eq. 1) then
            KVG%flag = 1
            KVG%A = "1"
        elseif(num .eq. 2) then
            KVG%flag = 1
            KVG%A = "2"
        end if
    else if(num .ge. 10 .and. num .le. 100) then
        kvg%flag = 2
        write(kvg%b,200)num
200     Format(2A)
    else
        kvg%flag = 3
        write(CA,*)num
        write(*,*)kvg%c
        stop 'here'
       
300    Format(I3)

    end if



    return
    end subroutine stringer

 

 

CA*11 throws an error, CA*12 does not. 

This is rough I am just playing with the code to get it as short and quick as possible.  

0 Kudos
9 Replies
LeonardB
New Contributor I
1,702 Views

It works if changing "write(CA,*) num" to "write(CA,'(I11)') num"

It looks like "write(CA,*) num" writes the integer on 11 positions plus a trailing blank into CA.  That sums up to 12 characters into CA that is sized to 11 characters.

 

 

0 Kudos
JohnNichols
Valued Contributor III
1,685 Views

The four rules of programming:

1. Do not program at 1 am.

2. You will have done it before - look for it.

3. Always say thank you when a kind soul reminds you of something you should already know. 

4. Fortran is to make our work easier, paraphrases Backus, ie being lazy can be useful. 

5. The last 4 rules were on the stone tablet that was to heavy to carry out of the wilderness. 

0 Kudos
cryptogram
New Contributor I
1,630 Views

Using * in the write gives too much leeway, there's no standard for how this has to behave, and it may be different between compiler versions.

 

If performance is an issue, try to avoid using internal I/O to do conversion.  I remember a version of CVF where this was incredibly slow.

A little math will get you what you want, like so:

program Console3

implicit none

integer num, i, num2,k
character*1 charnum(3), dummy

100 read(*,*) num
num2 = num
do i=1,3
k = mod(num2,10)
charnum(4-i) = char(48+k)
num2 = (num2-k)/10
end do
write(*,*) num, charnum
goto 100


end program Console3

If the char(48+k) makes you queasy, you could create a character array with "0" through "9" and look up

the character using k+1 as an index.  Or something with a substring; lot's of ways to skin this cat.

0 Kudos
JohnNichols
Valued Contributor III
1,599 Views

Thank you for your comment.  

I was really looking this time to make the code as compact as possible.  My original effort in another program is several hundred lines long with a lot of if statements.  

@jimdempseyatthecove  showed me how to shorten it, I was just trying to get it shorter.  

 

0 Kudos
JohnNichols
Valued Contributor III
1,592 Views

 

kvg%flag = 3
        write(CA,'(I3)')num
        write(*,*)CA(1:1)
        write(*,*)kvg%c
        write(kvg%c,'(I3)')num
        stop 'here'
 type stringRC

        character*1  ::  A
        character*2  ::  B
        character*3  ::  C
        character*4  ::  D
        character*1  ::  DA(4)
        integer  :: num
        integer :: flag
    end type stringRC

 

 

The problem I found was that the write statement at line 5, will work with character*3  C, but not character*1  CA(3) - I get an exception error.  

What is the difference between D and DA in storage terms and access?

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,559 Views

character*1  CA(3) declares variable CA as an array of three 1-character variables.

D is a single 4-character variable (len=4), whereas DA is an array of four 1-character (len=1) variables.

Thus

    write(kvg%da, '(I3)') num

Specifies an array of character variables as oppose to a single character variable (of appropriate length) to receive the formatted text. Apples and oranges.

While Fortran permits D=DA; DA=D with somewhat interchangeability, the WRITE to internal record is more stringent.

Steve L may add additional insight to this.

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
1,546 Views

While Fortran permits D=DA; DA=D with somewhat interchangeability, the WRITE to internal record is more stringent.

 

--------------------------------------------------------------------------------------------------------------------------------------

Jim:  Yes I found this out.  The interesting question is :  why have character*1  d(30) and character*30 D,  just pick one?

0 Kudos
Steve_Lionel
Honored Contributor III
1,484 Views

For internal files, an array is treated as a series of records, one per element. Does this help the understanding?

0 Kudos
JNichols
New Contributor I
1,430 Views

Thank you, yes.  The interesting feature of Fortran is the ability to build programs over decades from the same basic set of instructions.  Like all such organic growths one is left with an interesting hodge podge of rules and regulations.  The end result is much like a standard code of practice.  

This work comes about from looking at KMeans, it is an interesting problem and a method as noted by one source as useful for understanding FFT results.  But one needs graphs to view the results quickly and not rely on EXCEL.  DISLIN is not really suited to looking at results in multidimension arrays, it is for article preparation, not exploration.  

 

0 Kudos
Reply