dmb@morgoth.UUCP (David M. Brown) (07/08/88)
[IBM-AT...MS-Fortran...MS-DOS] I am writing an application which reads in data from a file. I want to be able to comment out lines of data. I did this on my old system (Ultrix on uVAX II) by using fseek(). It wasn't pretty but it worked. What I want to do is look at the first character in the line, and, if it's a '#', just go on to the next line. No problem there. But, if it's not, then I want to read data from the rest of the line. The backslash edit descriptor doesn't seem to work on input. The lines in the file are of various lengths, so direct access won't work. Anyone have any ideas? David Brown {harvard | ll-xn | mirror}!adelie!morgoth!dmb ICF Technology, Robinson Plaza II, Suite 200, Pittsburgh, PA 15205 (412) 788-9200 WE CHALLENGE our traditions BECAUSE we believe TRUTH without questioning IS FALSE
seibel@cgl.ucsf.edu (George Seibel) (07/11/88)
In article <472@morgoth.UUCP> dmb@morgoth.UUCP (David M. Brown) writes: >[IBM-AT...MS-Fortran...MS-DOS] >I am writing an application which reads in data from a file. I want >to be able to comment out lines of data. I did this on my old system >(Ultrix on uVAX II) by using fseek(). It wasn't pretty but it worked. >What I want to do is look at the first character in the line, and, if >it's a '#', just go on to the next line. No problem there. But, if it's >not, then I want to read data from the rest of the line. >The backslash edit descriptor doesn't seem to work on input. The lines >in the file are of various lengths, so direct access won't work. >Anyone have any ideas? The usual approach is to read a line into a buffer, then test the buffer to see if it has the characters that signify a real record. If it does, read it using an internal read. In this example, I assume a max record length of 80 chars, and read an integer and a real... parameter (LENREC=80) character*LENREC buffer c c --- read a line into the buffer --- c read(lunit,'(a)') buffer c c --- read data from buffer if not comment --- c if (buffer(1:1) .ne. '#') read(buffer,'(i5,f8.3)') idata, rdata c ... that's all. this is standard fortran 77, so you shouldn't have to mess around with fseek(), and it should work on any fortran 77 compiler. All you're doing here is substituting the name of a character variable that contains your data for the logical unit number in an otherwise standard read statement. This method is simple and suffices for most applications. You'll have to do formatted reads however; if you want to do a "free format read" from the buffer, then you'll have to parse it yourself. George Seibel, UCSF seibel@cgl.ucsf.edu
richard@calvin.EE.CORNELL.EDU (Richard Brittain) (07/12/88)
In article <11041@cgl.ucsf.EDU> seibel@hegel.mmwb.ucsf.edu.UUCP (George Seibel) writes: >In article <472@morgoth.UUCP> dmb@morgoth.UUCP (David M. Brown) writes: >>What I want to do is look at the first character in the line, and, if >>it's a '#', just go on to the next line. No problem there. But, if it's >>not, then I want to read data from the rest of the line. >......... > >The usual approach is to read a line into a buffer, then test the buffer >to see if it has the characters that signify a real record. If it does, >read it using an internal read. In this example, I assume a max record >length of 80 chars, and read an integer and a real... ....... example deleted >... that's all. this is standard fortran 77, so you shouldn't have to >mess around with fseek(), and it should work on any fortran 77 compiler. ......... >You'll have to do formatted reads however; if you want to do a "free format ^^^^^^^^^^^ >read" from the buffer, then you'll have to parse it yourself. ^^^^ >George Seibel, UCSF >seibel@cgl.ucsf.edu This is a very common situation in a lot of the programming which I am involved in, and I find the inability to perform a free format read from a character string a constant frustration. I never use a formatted read when a free format read will do as this makes life so much easier. Can anyone explain a good reason for this rule in the fortran standard? It has always seemed somewhat arbitrary to me. Richard Brittain, School of Elect. Eng., Upson Hall Cornell University, Ithaca, NY 14853 ARPA: richard@calvin.ee.cornell.edu UUCP: {uunet,uw-beaver,rochester,cmcl2}!cornell!calvin!richard
gil@mist.cs.orst.edu (Gil Bachelor) (07/13/88)
In article <490@calvin.EE.CORNELL.EDU> richard@calvin.ee.cornell.edu.UUCP (Richard Brittain) writes: >In article <11041@cgl.ucsf.EDU> seibel@hegel.mmwb.ucsf.edu.UUCP > (George Seibel) writes: >>In article <472@morgoth.UUCP> dmb@morgoth.UUCP (David M. Brown) writes: >>>What I want to do is look at the first character in the line, and, if >>>it's a '#', just go on to the next line. No problem there. But, if it's >>>not, then I want to read data from the rest of the line. >>......... >>The usual approach is to read a line into a buffer, then test the buffer >>to see if it has the characters that signify a real record. If it does, >>read it using an internal read. ... > ....... example deleted >>... that's all. this is standard fortran 77, so you shouldn't have to >>mess around with fseek(), and it should work on any fortran 77 compiler. > ......... >>You'll have to do formatted reads however; if you want to do a "free >>format read" from the buffer, then you'll have to parse it yourself. >>George Seibel, UCSF > >This is a very common situation in a lot of the programming which I am >involved in, and I find the inability to perform a free format read from >a character string a constant frustration. I never use a formatted read >when a free format read will do as this makes life so much easier. Can >anyone explain a good reason for this rule in the fortran standard? It has >always seemed somewhat arbitrary to me. > >Richard Brittain, School of Elect. Eng., Upson Hall > Cornell University, Ithaca, NY 14853 I don't know the reason for the rule. However, some versions of Fortran have been extended to allow free-format reads from internal files (character variables or arrays). For those versions that don't allow it, one can use a scratch file, as shown in this example: character line*80 integer n real x * Open unit 9 as a scratch file. open(9) * Use A-format input to read an 80-character line into * variable "line". 100 read (*,1000,end=200) line 1000 format(a) * Test the first character of "line"; if it is a '#', * go somewhere else. if (line(1:1) .eq. '#') goto 150 * Use A-format to write the line on the scratch file and * read it back, using list-directed input. rewind(9) write(9,1000) line rewind(9) read (9,*) n, x ... This may be considered a "kludge", but it works, and is a lot easier than writing your own number-conversion routines. ------------------------------------------------------------------ Gilbert A. Bachelor | Internet: gil@cs.orst.edu Dept. of Computer Science| UUCP: {hp-pcd,tektronix}!orstcs!gil Oregon State University | Corvallis, OR 97331 | Phone: (503) 754-3273
simon@alberta.UUCP (Simon Tortike) (07/15/88)
I'm responding to a request for processing comments at the start of lines in a FORTRAN input text file. Rather than reading the whole line in, I always call a "get comment" subroutine that reads in the first character of every line until it finds a line which is not commented out. The routine then backspaces one record and returns to the calling program. The read statements in the original program do not need to be altered, one only has to call the comment-eater before reading in a record. Surely that's easier than reading the entire line first? FYI, I use the following code to inspect data for comments. As I said, a call to this routine is made before reading a line of data, but it in no way affects how the read is performed (e.g. the formatting.) character comment*1 integer infile real foo(5) read (infile,'(a)',ERR=nnn) comment call getcmmt (infile, comment) read (infile, 666) foo(1), foo(2), foo(3), foo(4), foo(5) 666 format (...... subroutine getcmmt (unit, comment) c ********** ******* c routine to inspect line start for comment character. c suggest using 'read (unit,'(a)',ERR=nnn) comment' as first c line before any input. Then any character can serve as c a commented-line indicator by placing it in the first c column of the first line of the data file. see following routine. c implicit logical (a-z) integer unit character thechar*1, comment*1 c 100 read (unit,'(a)',err=998) thechar if (thechar .eq. comment) go to 100 backspace (unit, err=999) return 998 print *, ' Error reading unit ', unit, ' in "getcmmt"!!' return 999 print *, ' Error backspacing unit ', unit, ' in "getcmmt"!!' return end c ------------------- Simon Tortike Dept Min, Met & UUCP: ...{ubc-vision,mnetor}!alberta!simon Petroleum Engg BITNET: stortike@ualtavm Univ. of Alberta AGT: 403/432-3338 Edmonton, AB Canada T6G 2G6 *** No nifty notes or quotes, I'm sorry to say ***
EACELARI@pucc.Princeton.EDU (Edward A Celarier) (07/17/88)
In article <1450@pembina.UUCP>, simon@alberta.UUCP (Simon Tortike) writes: > .. Rather than reading the whole line in, I >always call a "get comment" subroutine that reads in the first character >of every line until it finds a line which is not commented out. The routine >then backspaces one record and returns to the calling program. The read >statements in the original program do not need to be altered, one only has >to call the comment-eater before reading in a record. Surely that's easier than >reading the entire line first? Perhaps so, but if the particular implementation you are using literally backspaces a device (not necessary for "blocked" files, unless the records are particularly long), this can really slow things down! I don't know the reason for the screwy Fortran standard, and, in fact, I was a bit surprised. All the machines I've been working on for the last couple of years (VAX/VMS and Gould) have surreptitiously supported reading free-formattedly from an internal file (character variable).
hirchert@uxe.cso.uiuc.edu (07/18/88)
Various people have asked why FORTRAN 77 doesn't allow list-directed input from an internal file. I wasn't a member of X3J3 when FORTRAN 77 was developed, but I think I can offer an intelligent guess: 1. People would think it strange to allow list-directed input and not list- directed output, but list-directed output is distinctly nonportable because of the differences in output formats used for list-directed output. (We're not just talking differences in what output looks like; we're talking differences in whether a program runs because the internal file may not be big enough to hold the generated output.) 2. Even list-directed input isn't as easy as some people think because of the difficulty in coping with the fact that list-directed input may or may not read additional records, depending on whether or not there were enough values on the first record. If one does enough parsing to determine how many values appear on the record, then it isn't that much more work to construct a format to read them. On the other hand, the draft Fortran 8x standard put out for public comment removed these restrictions and I don't think anyone complained about that, so eventually all Fortrans will probably let you do this (but that's no consolation today). Kurt W. Hirchert hirchert@ncsa.uiuc.edu National Center for Supercomputing Applications