Please consider this statement:
*
format(2i4,1 12(f4.1,1x,a2,1x,a5))
Is my understanding that this line reads : 2 integers of 4 digits and 12 groups of:
- a 4 digits float with one decimal
- one format space
- an alphabetic string of two chars
- one format space
- an alphabetic string of five chars
But I don't understand the one in the middle (marked with a star on top of it), can someone please explain what it means?
The given expression is supposed to parse:
59 229 7.2 Ms HRV 7.3 Mw P&S 7.3 Ms P&S 7.1 Ms ISC 7.2 Ms PAS 7.4 Ms BRK 6.3 mb ISC 6.2 mb NEIS
thanks
The compiler recognizes "1 12", which is probably a typo, as "112". The compiler ignores the space and doesn't notice the error because the format statement is syntactically correct.
The sample input that you provided would be parsed correctly with "8" in place of the "1 12". "12" would work as well, and I'm guessing that's what the author intended.
If your corresponding "read" statement is only asking for 26 items, it'll work OK with 112 anyhow because it stops parsing when it has gotten all the items you asked for.
found it: the symbol "1", quotes not part of the said symbol, means new line. Its just an odd, and if you ask me, antinatural, way to say \n.
thanks to everybody for helping.
Related
I am working on a project and as I have not coded with Fortran before, I am struggling a lot. My professor gave me a code file which I need to fix but I don't understand the syntax.
So, in the file he has
g = some formula,
1 some formula
2 * some formula
3 / some formula.
What does 1, 2, 3, * and / do?
I asked my Professor, and he said that this is Fortran 77 code and 1, 2, 3 are used as indexing in column 6 and the g is in column 7 as that's how the Fortran code is written. But I was very confused why Fortran 77 only accepts code after column 7?
Thank you for all the replies.
What you are most likely looking at is Fixed source-form statement continuation which is part of the Fixed source form.
Fixed-form formatting is an old way of formatting code which still stems from the old punched-cards. Lines could only be 72 characters long, but sometimes you needed more. Hence, the statement-continuation character:
Except within commentary, character position 6 is used to indicate continuation. If character position 6 contains a blank or zero, the line is the initial line of a new statement, which begins in character position 7. If character position 6 contains any character other than blank or zero, character positions 7–72 of the line constitute a continuation of the preceding non-comment line.
source: Fortran 2018 Standard, Section 6.3.3.3
Which character is used as statement-continuation marker, is up to the programmer and his style. Often you see a <ampersand>-character (&), or <dollar>-character ($) or the <asterisk>-character (*) like so:
c23456789012345678901234567890123456789012345678901234567890123456789012
g = something long
& + something_longer
& + something_even_longer
However, in the really old days, people often numbered their lines.
c23456789012345678901234567890123456789012345678901234567890123456789012
0g = something long
1 + something_longer
2 + something_even_longer
and because space was limited, they removed all spaces, which sometimes becomes very confusing when you have numbers in your line:
c23456789012345678901234567890123456789012345678901234567890123456789012
0g=1.2345+
10.35697-
22.5789
This does not add 10.35697 and subtract 22.5789, but adds 0.35697 and subtracts 2.5789
The usage of numbers as statement continuation markers is again inherited from the punched-cards. A single punched-card represented a single Fortran statement. And on the card, the row and column numbers were printed (Thanks to High Performance Mark for this information)
Note: the asterisk and slash in the OP are nothing more than the normal multiplication and division.
source txt file:
34|Gurla Mandhata|7694|25243|2788|Nalakankar Himalaya|30°26'19"N
81°17'48"E|Dhaulagiri|1985|6 (4)|China
command input:
:%s/\(\d\+\)\(\d\d\d\)/\1,\2/g
command output:
34|Gurla Mandhata|7,694|25,243|2,788|Nalakankar Himalaya|30°26'19"N
81°17'48"E|Dhaulagiri|1,985|6 (4)|China
Desired output:
34|Gurla Mandhata|7,694|25,243|2,788|Nalakankar Himalaya|30°26'19"N
81°17'48"E|Dhaulagiri|1985|6 (4)|China
Basically 1985 is supposed to be 1985 and not 1,985. I tried to put a \? so every time the pattern matches it stops and a °+ after so it has to detect a ° to match the pattern, but no success. It just replaces the ° and everything before that, complete mess.
My knowledge of regular expressions however combined with the substitute is weak and I'm stuck here.
EDIT
the first 3 numbers represent heights of mountains, those 3 need to change with a (,) and the last number ( 1985 ) represents a year, which must not be changed.
Mathematical solutions are not going to work as loophole since there are mountains with a height off less than 1900
You haven't told us what is the difference between 1985 and other numbers, so I assumed that your "small" numbers are less than 2000.
You almost got it:
:%s/(\d*[2-90])(\d\d\d)/\1,\2/g
Alternatively if that isn't what you want, you can use c flag (:h s_flags):
:%s/\(\d\+\)\(\d\d\d\)/\1,\2/gc
this line will leave the last 3 columns untouched, just do substitution on the content before it:
%s/\v(.*)((\|[^|]*){3}$)/\=substitute(submatch(1),'\v(\d+)(\d{3})','\1,\2','g').submatch(2)/g
Note that the above line will change 1000000 into 1000,000 instead of 1,000,000. Vim's printf() doesn't support %'d, it is pity. If you do have number > 1m, we can find other solutions.
update
I solved it myself, by using 3 seperate commands; one for every number string in the file:
%s/^\(\d*|[^|]*|\)\(\d\+\)\(\d\d\d\)|/\1\2,\3|/g
:%s/^\(\d*|[^|]*|\d\+,*\d*|\)\(\d\+\)\(\d\d\d\)|/\1\2,\3|/g
:%s/^\(\d*|[^|]*|\d\+,*\d*|\d\+,*\d*|\)\(\d\+\)\(\d\d\d\)|/\1\2,\3|/g
In case you want to use perl:
:%!perl -F'\|' -lane 'for(#F[2..4]) { s/(\d+)(\d{3})/\1,\2/;} print join "|", #F'
I'm attempting to block a long string of unnecessary text that's on every page of a document.
Ex: "36075 This is another page and this is the date March 4 2013"
I know this must be very simple, but I'm hoping there is a way to block text verbatim. Is the only way to block this text by using a lot of /d/s/w+/+ etc or is there is a way to say, "match 36075 This is another page and this is the date March 4 2013".
This would be SO HELPFUL to know. Thank you for helping!
From what you wrote I assume you need to get leading numbers from string, to do it you just need to use this pattern: ^\d+ which from this input:
36075 This is another page and this is the date March 4 2013
will return this:
36075
For future, in case of such questions please provide example string and expected output. As well as what you have tried.
I realized the issue I was having. I didn't need to use RegEx. The program I was using has the functionality to match specific words or groups of words and pronounce them differently. What I discovered is that it will not match the words unless the word groups are input exactly the way the program typically reads them.
Ergo --> The channel saw
the end of the British hold over
Would have to be listed as one group for, "The channel saw" and a second group for "the end of the British hold over"
In addition, there were some numbers --> 11960_30_o_ho_
and if the program naturally read 119 and then 60_3 and then _o_ho_ then three strings would need to be input for each section.
A few frustrating hours later, problem solved :) Thank you for your assistance.
I'm trying to do a search within a visual block, (from a vimscript).
This is my code:
aaaaaaaaaaaa
a26 text tea
atext text a
atext 27 12a
a11 text 25a
aaaaaaaaaaaa
Let say my block selection is within the 'a' border and I want to search all numbers with 2 characters:
This is my search:
/\%V\d\{2}\%V
The problem with the 2nd \%V is that it shortened a visual block selection with 1 characters, it doesn't find the number 12 and 25 in my above example.
How can I extend the visual block selection (in a vimscript) with 1 character to the right, do the search and return to previous visual block selection?
OK, then I just write it as an answer, well this is an answer and question...:)
remove the 2nd \%V from your pattern would do this.
I posted first as comment, because.....
I personally have been using only single \%V in my work, and it worked fine. I saw this question, and checked the :h \%V, the help suggests using both... and it is zero-width. I don't really get why 2 \%Vs won't work for OP's question.
so, that is to say, I know how to fix the problem, but not 100% clear, what causes the problem, I hope others could explain a bit.
I need help forming regex to limit user input to only numerics and only up to 10 occurrences.
I have regex that is working to keep input to numerics only, but I cannot limit it to up to 10.
Here is what I have:
^(0|[1-9][0-9]*)$
I am okay accepting negative numbers, decimals, and 0's. Any advice?
^\s*([0-9)+){0,10}\s*$
This basically says I want to 0 to 10 things, where each thing is all digits. I added the \s* on either side to allow the user to have put spaces before or after their numbers. This would accept things like
10 1231231 1231 1231 23112 123123
If what you really want is just a single number, that is only up to 10 digits, it is even easier:
^\s[0-9]{1,10}\s$
The regex you're looking for is this:
/(?=^[-+]?\d*\.?\d+$)^.{1,10}$/
Keep in mind that this regex will allow maximum length of input to 10 which includes optional + or - sign at start and a decimal point ..
you can try this:
^(?<=\s)(\-?[\d]{1,10}(?=\s))$
This fails as it has 11 digits
Debug.WriteLine(Regex.IsMatch("12345678901", #"^\d{1,10}$").ToString());
Posted the above answer before you clarified you want up to 10 set of numbers delimited by space.
Tested the accepted answer and in .NET Regex it fails for me.
Even fixing the syntax error it still does not parse by space
Give this a try
Debug.WriteLine(Regex.IsMatch(" 12345 678901 12 ", #"^\s*([+-]?\d+)(\s+[+-]?\d+){1,9}\s*$").ToString());