Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!

integer to character string.

JohnNichols
Valued Contributor II
591 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
546 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.

 

 

JohnNichols
Valued Contributor II
529 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. 

cryptogram
Beginner
474 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.

JohnNichols
Valued Contributor II
443 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.  

 

JohnNichols
Valued Contributor II
436 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?

jimdempseyatthecove
Black Belt
403 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

JohnNichols
Valued Contributor II
390 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?

Steve_Lionel
Black Belt Retired Employee
328 Views

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

JNichols
Beginner
274 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.  

 

Reply