Software Archive
Read-only legacy content
17060 Discussions

String formatting

Intel_C_Intel
Employee
1,033 Views
Hello,

I wonder why the following two methods of filling the strings fmt(i), generate different results.
In the debugger the strings appear to be exactly the same, but writing the strings using the format statement generates different results.

The first method gives: 'F9.0 '
The second method gives: 'F9.0 F6.0 '

 
implicit none 
character(6)  :: fmt(4) 
character(12) :: bufstr(2) 
interface 
  character(6) function frmt(cs) 
    character(6), intent(in) :: cs 
  end function 
end interface 
 
fmt(1)=frmt('F9.0') 
fmt(2)=frmt('F6.0') 
write(bufstr(1),100) fmt(1),fmt(2) 
fmt(3)='F9.0' 
fmt(4)='F6.0' 
write(bufstr(2),100) fmt(3),fmt(4) 
100 format(A,A) 
end 
 
character(6) function frmt(cs) 
  character(6), intent(in) :: cs 
  frmt=cs 
end function 


It seems to be a hidden length problem, because when I fool the compiler by defining the function frmt as character(4) in the interface section. the result is again as it should be.

Thanks,

Walter Kramer
0 Kudos
6 Replies
Intel_C_Intel
Employee
1,033 Views
Sorry, wrong tags:

Hello,

I wonder why the following two methods of filling the strings fmt(i), generate different results.
In the debugger the strings appear to be exactly the same, but writing the strings using the format statement generates different results.

The first method gives: 'F9.0 '
The second method gives: 'F9.0 F6.0 '

 
implicit none  
character(6) :: fmt(4)  
character(12) :: bufstr(2)  
interface  
  character(6) function frmt(cs)  
    character(6), intent(in) :: cs  
  end function  
end interface  
 
fmt(1)=frmt('F9.0')  
fmt(2)=frmt('F6.0')  
write(bufstr(1),100) fmt(1),fmt(2)  
fmt(3)='F9.0'  
fmt(4)='F6.0'  
write(bufstr(2),100) fmt(3),fmt(4)  
100 format(A,A)  
end  
 
character(6) function frmt(cs)  
  character(6), intent(in) :: cs  
  frmt=cs  
end function  


It seems to be a hidden length problem, because when I fool the compiler by defining the function frmt as character(4) in the interface section. the result is again as it should be.

Thanks,

Walter Kramer
0 Kudos
Intel_C_Intel
Employee
1,033 Views
Walter,
A recent thread introduced me to the Memory Debug Window. Set a breakpoint on your "end" statement and run to that point. Open the Memory window and type fmt as the Address. You'll see that the last two characters of fmt(1) and fmt(2) are NULs (x00), while the last two characters of fmt(3) and fmt(4) are spaces (x20). Looks like the actual arguments have to be padded to six characters.

Dick
0 Kudos
Intel_C_Intel
Employee
1,033 Views
Dick, thank you.

Luckily I didn't have to pad the actual argument with spaces. I now use character(*) as type definition for the argument. This solves the problem.

Walter
0 Kudos
Intel_C_Intel
Employee
1,033 Views
I am still curious.
If actual character argument A is passed to dummy argument B, and A has less characters than B, then B will be padded with NUL characters. In an ordinary assignment B=A, B will be padded with blanks.
I this a consequence of passing by reference?

Walter
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,033 Views
Well, when a constant, such as string literal 'F6.0' has to be passed
into routine by reference, compiler has to "make up" a real address of
it somehow. Now, Compaq's experts could tell you better, but it
can be done either by:

a) passing the address where the constant is actually stored in the
image of .exe file itself or

b) creating a space somewhere on the stack, filling it with the
value of the constant and passing address of that space.

In your case, what you get as value of the actual argument, is your
constant plus whatever happened to be immediately behind the space in memory where it is stored. I guess you're just lucky that you get CHAR(0)
there, but I may be wrong. Point is, that the declaration of dummy argument (LEN=6) just overrides the actual length of the constant (passed
as hidden argument), which is 4 in the example.
With simple assignment (B=A) compiler "knows" what's the right thing to
do, since it has all information present; with your sample, it perhaps could deduce that it should pad the rest with blanks, but it apparently doesn't,
and I wouldn't blame Compaq for that.

Btw, I deem declaring character arguments other than (LEN=*) bad practice and I don't see why otherwise would it allowed at all -- perhaps someone can tell a good reason, but I don't see it right now.

Jugoslav
0 Kudos
Intel_C_Intel
Employee
1,033 Views
Jugoslav, thanks for your explanation. In the future I will follow your advise and declare all character dummy arguments with (LEN=*).

Walter Kramer
0 Kudos
Reply