reeder@ut-emx.UUCP (William P. Reeder) (09/19/89)
I was porting NCAR Graphics (version 2.01) to an Alliant yesterday when I got a compilation error on the third line of the following code fragment: character*80 ncarg call getenv('NCARGLIB', ncarg) if (ncarg.eq."") then A quick look in the standard confirmed that a character constant must contain one or more characters between the apostrophies. Yes, I know that those are quotes up there; NCAR must be assuming that all compilers allow quotes in place of apostrophies in addition to assuming that everyone allows null strings and lower case letters. Anyway, I need to check for a null string in variable "ncarg". I thought about using the intrinsic function LEN, but that just told me the size of the character variable (80), not the length of the string stored there (which may be less than 80). Is this the proper behavior for LEN? I can see where you would want to know how much storage was available in a character variable, but I want to know the length of a string stored in that variable much more frequently. I didn't see any standard intrinsic function defined which might give me this information. The best idea I have come up with so far for creating a "null" string is this: character*80 null write ( null, * ) Does anyone have any better ideas? -- William "Wills" Reeder, The University of Texas at Austin, Computation Center reeder@emx.utexas.edu, uunet!cs.utexas.edu!ut-emx!reeder, (512)471-3241 DISCLAIMER: Opinions expressed above are those of the author and do not necessarily reflect the opinions of The University of Texas at Austin, or those of the manufacturer of the wires which carried this message.
maine@elxsi.dfrf.nasa.gov (Richard Maine) (09/20/89)
In article <18585@ut-emx.UUCP> reeder@ut-emx.UUCP (William P. Reeder) writes: > Anyway, I need to check for a null string in variable "ncarg". I thought > about using the intrinsic function LEN, but that just told me the > size of the character variable (80), not the length of the string stored > there (which may be less than 80). Is this the proper behavior for LEN? > I can see where you would want to know how much storage was available > in a character variable, but I want to know the length of a string stored > in that variable much more frequently. I didn't see any standard > intrinsic function defined which might give me this information. Yes, its behavior is correct. The situation where I know that LEN is of most use is in a subroutine with a character*(*) argument. Of course it can also be useful to avoid hard-coding constants multiple places in the program so that later changes are easier. There is no way (within the standard) to do what you are trying to do. FORTRAN 77 does not allow null strings in any context, so you are not going to be able to come up with a standard way of making or detecting them. In fact, FORTRAN 77 has no concept of variable-length strings at all (niether does 8x, if I recall correctly). That's why LEN doesn't do what you think, because FORTRAN 77 does not support the concept you are thinking of. The character*(*) arguments are not variable length, though many people sloppily use such terminology for them (the standard doesn't). > The best idea I have come up with so far for creating a "null" string > is this: > character*80 null > write ( null, * ) That won't work either, for 2 reasons. 1) There ain't no such animal as a null string. This will just fill the string with blanks, which is quite a different thing than a null string. 2) List-directed i/o to internal files is illegal anyway. Some compilers support it, but not all. (8x does allow it). > Does anyone have any better ideas? If you want to check for a blank string, that's easy, but I assume you are making a distinction here. If you really want to check for null strings, its going to have to be outside of the context of standard FORTRAN. Perhaps there is a system call you can use to get the required info instead of trying to get the string into a FORTRAN string and then deduce things from that. -- Richard Maine maine@elxsi.dfrf.nasa.gov [130.134.1.1]
reeder@ut-emx.UUCP (William P. Reeder) (09/20/89)
In article <18585@ut-emx.UUCP>, I wrote: > The best idea I have come up with so far for creating a "null" string > is this: > > character*80 null > write ( null, * ) > > Does anyone have any better ideas? Well, after a little more thought (and then someone wrote me a letter with the same thoughts), it becomes clearer that FORTRAN has BLANK strings, not NULL strings. I came to this conclusion by thinking about how character strings are compared with relational operators: shorter strings are considered to be padded to the longer length with blanks. So, all I have to do is change if (ncar.eq."") then with if (ncar.eq.' ') then and everything is hunky-dory and standard conforming (except for those lower-case letters :-). Thanks for your time. -- William "Wills" Reeder, The University of Texas at Austin, Computation Center reeder@emx.utexas.edu, uunet!cs.utexas.edu!ut-emx!reeder, (512)471-3241 DISCLAIMER: Opinions expressed above are those of the author and do not necessarily reflect the opinions of The University of Texas at Austin, or those of the manufacturer of the wires which carried this message.
bernhold@qtp.ufl.edu (David E. Bernholdt) (09/20/89)
In article <18585@ut-emx.UUCP> reeder@ut-emx.UUCP (William P. Reeder) writes: >I was porting NCAR Graphics (version 2.01) to an Alliant... >I thought about using the intrinsic function LEN, but that just told me the >size of the character variable (80), not the length of the string stored >there (which may be less than 80). >I didn't see any standard >intrinsic function defined which might give me this information. Many (not all, however) UNIX Fortrans include a function called LNBLNK in their library. This returns the index of the "Last Non-BLaNK" position in the string. I just checked on an Alliant I have access to & its there. It is also present on Sun, Titan, Encore. It is not present on Balance or Cray, but for those and others it is quite easy to write in portable Fortran77. I have done this and use it in virtually all of my programs -- its the only way to get nice formatting of strings. I would be glad to send a copy to anyone who's interested, but its only 14 lines of actual code! BTW, the first public comment draft of the F8x standard included the same function under a different name. I don't know if its still there, but I hope so! -- David Bernholdt bernhold@qtp.ufl.edu Quantum Theory Project bernhold@ufpine.bitnet University of Florida Gainesville, FL 32611 904/392 6365
brainerd@unmvax.unm.edu (Walt Brainerd) (09/20/89)
In article <676@orange19.qtp.ufl.edu>, bernhold@qtp.ufl.edu (David E. Bernholdt) writes: > Many (not all, however) UNIX Fortrans include a function called LNBLNK > in their library. This returns the index of the "Last Non-BLaNK" > position in the string. > > 14 lines of actual code! > > BTW, the first public comment draft of the F8x standard included the same > function under a different name. I don't know if its still there, but > I hope so! Here is the mentioned function in 14 / 2 lines. Puzzle: even one of these lines is not necessary; which is it? This also illustrates how the LEN function is useful in a subprogram. It is still in F8x; the name is LEN_TRIM. Kind of silly when it could be a part of a standardized string-handling module. FUNCTION LENTRM (STRING) CHARACTER *(*) STRING DO 10 LENTRM = LEN (STRING), 1, -1 IF (STRING (LENTRM:LENTRM) .NE. ' ') RETURN 10 CONTINUE LENTRM = 0 END -- Walt Brainerd Unicomp, Inc. brainerd@unmvax.cs.unm.edu 2002 Quail Run Dr. NE Albuquerque, NM 87122 505/275-0800
userAKDU@ualtamts.BITNET (Al Dunbar) (09/20/89)
In article <MAINE.89Sep19132931@altair.dfrf.nasa.gov>, maine@elxsi.dfrf.nasa.gov (Richard Maine) writes: >In article <18585@ut-emx.UUCP> reeder@ut-emx.UUCP (William P. Reeder) writes: > >> Anyway, I need to check for a null string in variable "ncarg". I thought --- text deleted --- > >In fact, FORTRAN 77 has no concept of variable-length strings at all >(niether does 8x, if I recall correctly). ... Correct! However, the German representatives to WG5 proposed such a thing. Rather than putting it directly into the standard at this late date, however, a compromise was reached. The concept of "non-advancing I/O" was added to 8X as a feature that would facilitate the development of a "standard module" that could provide "varying character" capability. Without being party to the discussions that produced this proposal, I am forced to conclude that it seems poorly thought out. It SHOULD have been a more complete implementation of "stream I/O", preferably allowing for asynchronous, character at a time I/O with serial devices. The idea of adding a marginally useful feature to the language just to simplify the development of a useful extension, rather than adding the extension itself, seems a particulary poor approach to the standardization process. In article <18603@ut-emx.UUCP>, reeder@ut-emx.UUCP (William P. Reeder) writes: >In article <18585@ut-emx.UUCP>, I wrote: --- text deleted --- >length with blanks. So, all I have to do is change > if (ncar.eq."") then >with > if (ncar.eq.' ') then >and everything is hunky-dory and standard conforming (except for those >lower-case letters :-). That is what I would have suggested to you. Unfortunately, there are some situations in which the absence of a string is NOT the same as the presence of a blank one. A case in point is the "environment variables" of PC/MS-DOS and other systems. The code you suggest would be unable to differentiate between the non- existence of the variable and its existence with a "blank" value. To do that would require an interface to getenv that provided the length of the returned string. Alternately, you _might_ be able to look for the null character terminating the string returned (IFF that is how the string is indeed returned): lencar = index( ncar, char(0) ) - 1 if (lencar .eq. 0) then write (*,*) 'null string' elseif(lencar .gt. 0) then write (*,*) 'len=', lencar, ', string=(', ncar(:lencar), ')' else write (*,*) 'no null terminator' endif -------------------+------------------------------------------- Alastair Dunbar | Edmonton: a great place, but... Edmonton, Alberta | before Gretzky trade: "City of Champions" CANADA | after Gretzky trade: "City of Champignons" -------------------+-------------------------------------------
userAKDU@ualtamts.BITNET (Al Dunbar) (09/21/89)
In article <676@orange19.qtp.ufl.edu>, bernhold@qtp.ufl.edu (David E. Bernholdt) writes: >In article <18585@ut-emx.UUCP> reeder@ut-emx.UUCP (William P. Reeder) writes: >>I was porting NCAR Graphics (version 2.01) to an Alliant... --- text deleted --- > >BTW, the first public comment draft of the F8x standard included the same >function under a different name. I don't know if its still there, but >I hope so! It is still there, as LEN_TRIM, which is a bit more expressive and 8x-like than my own LENNB (Non Blank LENgth). -------------------+------------------------------------------- Alastair Dunbar | Edmonton: a great place, but... Edmonton, Alberta | before Gretzky trade: "City of Champions" CANADA | after Gretzky trade: "City of Champignons" -------------------+-------------------------------------------
khb%chiba@Sun.COM (chiba) (09/21/89)
In article <2475@ualtamts.BITNET> userAKDU@ualtamts.BITNET (Al Dunbar) writes: > > varying length string discussion > >Correct! However, the German representatives to WG5 proposed such a >thing. Such things have been repeatedly proposed over the last decade. The German representive (singular) may have also done so .... but such proposals predate his (and my) particpation in x3j3. There is a strong feeling that the language is large enough (or too large :>) and that varying length string modules are easily constructed (and, in fact, jerry w. the vice-chair even showed one back in 1985) >Rather than putting it directly into the standard at this late date, >however, a compromise was reached. The concept of "non-advancing I/O" was Has nothing to do with varying length string proposals. Non-advancing IO was chosen in preference to "stream IO" during a protracted design, review and debate process. I can't promise you it is better; but it was chosen _after_ due deliberation. >more complete implementation of "stream I/O", preferably allowing for >asynchronous, character at a time I/O with serial devices. The Asynchronous IO is very hard to specify in a completely OS independent fashion. The current proposal should cover character at a time (though one expects there to be efficencies for grabing more per transaction) and asynch extentions are probably planned by most of the vendors whose operating systems support such things. >development of a useful extension, rather than adding the extension >itself, seems a particulary poor approach to the standardization >process. True. But that isn't how it happened. Keith H. Bierman |*My thoughts are my own. !! kbierman@sun.com It's Not My Fault | MTS --Only my work belongs to Sun* I Voted for Bill & | Advanced Languages/Floating Point Group Opus | "When the going gets Weird .. the Weird turn PRO"