Fortran: How to read to an array from a file - io

I'm trying to read integers from a file to an array. But I get an error when I run the program.
PROGRAM MINTEM
INTEGER TEMP(4,7), I, J, MINIMUM, CURRENT
OPEN(UNIT=1, FILE='temps.dat')
READ (1,*) ((TEMP(I,J),J=1,7),I=1,4)
MINIMUM = TEMP(1,1)
DO I = 1,4
DO J = 1,7
IF (TEMP(I,J) < MINIMUM) THEN
MINIMUM = TEMP(I,J)
END IF
END DO
END DO
PRINT *, "MINIMUM TEMPERATURE = ", MINIMUM
END PROGRAM MINTEM
Input file looks like this:
22
100 90 80 70 60 100 90 80 70 60 100 90 80 70 60 100 90 80 70
100 90

The file you provided can be read in using this:
integer, allocatable :: t(:)
open(1,file='temp.dat')
read(1,*) N ! your first line with 22
allocate( t(N-1) ) ! further on you only have 21 elements
read(1,*)t ! so, read them in
print*, t
deallocate(t)
close(1)

Related

Why Scapy recalculates fragmentation size?

I am trying to fragment 120 bytes IP payload by 100 bytes. However, in output I got two packets one with 138 bytes and other with 50 bytes (Ethernet and IP header size are 14 and 20 bytes respectively). In first packet data offset starts from 0 to 103 and for second packet data offset starts from 104 to 119. Firstly I cannot understand why it works in this way. In order to understand I tried to look to source of defined fragment function in layers/inet.py line 552.
Scapy recalculates fragmentation size as follows:
def fragment(self, fragsize=1480):
"""Fragment IP datagrams"""
fragsize = (fragsize + 7) // 8 * 8 # <- RECALCULATION OF FRAGMENT SIZE
lst = []
fnb = 0
fl = self
while fl.underlayer is not None:
fnb += 1
fl = fl.underlayer
for p in fl:
s = raw(p[fnb].payload)
nb = (len(s) + fragsize - 1) // fragsize
for i in range(nb):
q = p.copy()
del(q[fnb].payload)
del(q[fnb].chksum)
del(q[fnb].len)
if i != nb - 1:
q[fnb].flags |= 1
q[fnb].frag += i * fragsize // 8
r = conf.raw_layer(load=s[i * fragsize:(i + 1) * fragsize])
r.overload_fields = p[fnb].payload.overload_fields.copy()
q.add_payload(r)
lst.append(q)
return lst
Can somebody explain why it is doing so?
N.B:
Ethernet header size 14 byte
IPv4 header size 20 byte
See https://github.com/secdev/scapy/issues/2424#issuecomment-576879663
From https://www.rfc-editor.org/rfc/rfc791#section-3.2 (page 25, top):
If an internet datagram is fragmented, its data portion must be broken on 8 octet boundaries.
To answer your question, fragment size must be a multiple of 8.
104 is a multiple of 8, not 100

SAS - Replace the n'th word in a string, if a certain length

I have a list of customer ids, formatted as follows:
123-456-78;
123-345-45;
12-234-345;
123-34-456;
I want to be able to find every 2-digit portion of the code and replace it with a new number. For example, "78" in the first entry, but "12" in the third entry.
Right now I'm using the scan function with a do loop to find each 2-digit section.
data work.test12;
set MyLib.customers;
do i=1 to 5;
x=scan(customer_id,i,'-');
if length(x)=2 then
do;
<??????>;
end;
output;
end;
I think regular expression will work nicely.
33 data _null_;
34 infile cards dsd dlm=';';
35 input s :$16.;
36 if _n_ eq 1 then rx = prxparse('s/(^|-)\d\d($|-)/\100\2/');
37 retain rx;
38 length new $16;
39 if prxmatch(rx,strip(s)) then new=prxchange(rx,1,strip(s));
40 put s= new=;
41 cards4;
s=123-456-78 new=123-456-00
s=123-345-45 new=123-345-00
s=12-234-345 new=00-234-345
s=123-34-456 new=123-00-456
The SCAN method can be greatly simplified and I speculate efficiency improved using CALL SCAN and SUBSTR on the left. CALL SCAN returns the position and LENGTH of the sub-string without extracting anything which you don't need.
33 data _null_;
34 infile cards dsd dlm=';';
35 input s :$16.;
36 put 'NOTE: ' s= #;
37 do i = 1 by 1 until(p eq 0);
38 call scan(s,i,p,l);
39 if l eq 2 then substr(s,p,l)='00';
40 end;
41 put s=;
42 cards4;
NOTE: s=123-456-7 s=123-456-7
NOTE: s=123-456-78 s=123-456-00
NOTE: s=123-345-45 s=123-345-00
NOTE: s=12-234-345 s=00-234-345
NOTE: s=123-34-456 s=123-00-456
Is the desired 2-digit number the same for all replacements?
You can use scan and tranwrd, but you need to ensure you don't replace the leading or trailing 2 digits of 3-digit numbers also. You can do this by padding both the old & new 2-digit number with hyphens, and by padding the whole customer_id too :
%LET NEW_NUM = 99 ; /* The number to convert all 2-digits to */
data want ;
set mylib.customers ;
do i = 1 to countw(customer_id,'-') ;
num = scan(customer_id,i,'-') ;
if length(num) = 2 then do ;
/* add leading & trailing - */
temp_customer_id = cats('-',customer_id,'-') ;
/* switch the 2-digit numbers */
tran_customer_id = tranwrd(temp_customer_id,cats('-',num,'-'),cats('-',"&NEW_NUM",'-')) ;
/* drop the leading & trailing - */
tran2_customer_id = substr(tran_customer_id,2,length(tran_customer_id)-2) ;
end ;
run ;

Octave advanced textread usage, bash

I have following text file:
079082084072079032084069067072000000000,0
082078032049050032067072065082071069000,1
076065066032065083083084000000000000000,0
082078032049050072082000000000000000000,1
082078032049050072082000000000000000000,1
082078032049050072082000000000000000000,1
070083087032073073032080068000000000000,0
080067065032049050032072082000000000000,0
082078032056072082000000000000000000000,1
070083087032073073073000000000000000000,0
082078032087069069075069078068000000000,1
082078032049050072082000000000000000000,1
077065073078084032077069067072032073073,0
082078032049050072082000000000000000000,1
080067065032049050032072082000000000000,0
082078032049050072082000000000000000000,1
I need too matrices:
X size 16x13
Y size 16x1
I want to separate each row of the file into 13 values, example:
079 082 084 072 079 032 084 069 067 072 000 000 000
Is it possible to import it into octave using textread function?
If no, can it be done using Linux bash command?
Yes, you can do this with textscan (see bottom if you really want to use textread:
octave> txt = "079082084072079032084069067072000000000,0\n082078032049050032067072065082071069000,1";
octave> textscan (txt, repmat ("%3d", 1, 13))
ans =
{
[1,1] =
79
82
[1,2] =
82
78
[1,3] =
84
32
[1,4] =
72
49
[...]
Note that you are reading them as numeric values, so you do not get the preceding zeros. If you want them, you can either read them as string by using "%3s" in the format (extra trouble to handle and reduced performance since you will then be handling cell arrays).
Since you are reading from a file:
[fid, msg] = fopen ("data.txt", "r");
if (fid)
error ("failed to fopen 'data.txt': %s", msg);
endif
data = textscan (fid, repmat ("%3d", 1, 13));
fclose (fid);
If you really want to use textread:
octave> [d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13] = textread ("data.txt", repmat ("%3d", 1, 13))
d1 =
79
82
76
[...]
d2 =
82
78
65
[...]
or:
octave> data = cell (1, 13);
octave> [data{:}] = textread ("data.txt", repmat ("%3d", 1, 13))
data =
{
[1,1] =
79
82
76
[...]
[1,2] =
82
78
65
[...]
If you need to capture the value after the comma (not really part of your original question), you can use:
octave> textscan (txt, [repmat("%3d", 1, 13) ",%1d"])
ans =
{
[1,1] =
79
82
[1,2] =
82
78
[1,3] =
84
32
[...]
[1,14] =
0
1
}
You can do this pretty easily by reading three characters at a time using read in the shell:
while IFS="${IFS}," read -rn3 val tail; do
[[ $tail ]] && echo || printf '%s ' "$val"
done < file
This implementation assumes that if we encounter a value after the comma, we should go to the next line.

Pulling random string from predefined strings in qbasic

So i am making a random map generator in QBasic for Battlefield 3.
The idea is, whenether i run the program, the program should print a map name from already predefined strings. The code i have so far is:
CLS
REM --------------------- RANDOM NUMBER VALUE --------------------------
RANDOMIZE TIMER: A = INT((RND * 100)): B = INT((RND * 10)): C = (A + B)
NUM = INT(C - (RND * 10))
REM --------------------------- MAPS - -------------------------------
A$ = "Caspian Border"
B$ = "Damavant Peak"
C$ = "Grand Bazaar"
D$ = "Kharg Island"
E$ = "Norshar Canals"
F$ = "Operation Firestorm"
G$ = "Operation Metro"
H$ = "Seine Corssing"
I$ = "Tehran Highway"
REM ----------------------------- GAME MODE ----------------------------
RSH$ = "Rush"
TDM$ = "Team Deathmatch"
CQS$ = "Conquest"
CQSL$ = "Conquest Large"
SQDM$ = "Squad Deathmatch"
REM --------------------------- PLAYER COUNT -----------------------------
AA$ = "16 Players"
BB$ = "32 Players"
CC$ = "64 Players"
REM ------------------------ PROCESSING CODE ----------------------------
PRINT "Bore-o-mat 3000 Initilaized"
PRINT "The random number is"; NUM; "therfore the map drawn is:"
IF NUM > 10 THEN PRINT A$
IF NUM > 20 THEN PRINT B$
IF NUM > 30 THEN PRINT C$
IF NUM > 40 THEN PRINT D$
IF NUM > 50 THEN PRINT E$
IF NUM > 60 THEN PRINT F$
IF NUM > 70 THEN PRINT G$
IF NUM > 80 THEN PRINT H$
IF NUM > 90 THEN PRINT I$
END
Lets say the random NUM is 22.
It checks if NUM is bigger than 10 and prints A$, because 22 > 10. It does the same for B$. When it comes to C$, the program breaks as NUM is not > 30. Thats normal. The problem is that i get more than one map name. I get a few. Reffer to the picture:
http://i.stack.imgur.com/TTnXQ.png
I want only one string based of the random number.
How do i break the code from going to the next line?
Is there a simpler way of pulling random strings?
Like i run the program and it pulls a random string out of the A$, B$, C$ etc.
Cheers :)
You should really put the strings in an array. Otherwise, here's a quick fix.
IF NUM >= 10 AND NUM < 20 THEN PRINT A$
IF NUM >= 20 AND NUM < 30 THEN PRINT B$
IF NUM >= 30 AND NUM < 40 THEN PRINT C$
IF NUM >= 40 AND NUM < 50 THEN PRINT D$
IF NUM >= 50 AND NUM < 60 THEN PRINT E$
IF NUM >= 60 AND NUM < 70 THEN PRINT F$
IF NUM >= 70 AND NUM < 80 THEN PRINT G$
IF NUM >= 80 AND NUM < 90 THEN PRINT H$
IF NUM >= 90 AND NUM < 100 THEN PRINT I$
You could place them into an array and then select one randomly:
A$(1) = "Caspian Border"
A$(2) = "Damavant Peak"
A$(3) = "Grand Bazaar"
A$(4) = "Kharg Island"
A$(5) = "Norshar Canals"
A$(6) = "Operation Firestorm"
A$(7) = "Operation Metro"
A$(8) = "Seine Corssing"
A$(9) = "Tehran Highway"
Num = INT(RND * 9 + 1)
PRINT A$(Num)

multiple splittings

I need a better way of doing this any ideas?
$strOutput = "800x600, 32 bits # 60 Hz."
# Initial split
$aSplitString = $strOutput.Split(",")
# Get Horizontal and Vertical Length
$aSplitString2 = $aSplitString[0].Split("x")
$strHorizontal = $aSplitString2[0]
$strVertical = $aSplitString2[1]
$aSplitString2 = $null
#Get Color Depth and Frequency
$aSplitString2 = $aSplitString[1].Split(" ")
$strColour = $aSplitString2[1]
$strFrequency = $aSplitString2[4]
Not a fan of using so many split functions on one string. What else could I do?
I am trying to get the individual resolution sizes, the color depth and the frequency into their on variables in the above example;
horizontal = 800
vertical = 600
color = 32
frequency = 60
I've found that we can pass an array of chars to the split function.
So, in one line :
PS C:\Windows\system32> "800x600, 32 bits # 60 Hz.".split(#("x",","," "))
800
600
32
bits
#
60
Hz.
one way is:
$strOutput = "800x600, 32 bits # 60 Hz."
$splitted = $strOutput -replace '\D',' ' -split '\s+'
$strHorizontal = $splitted[0]
$strVertical = $Splitted[1]
$strColour = $splitted[2]
$strFrequency = $splitted[3]

Resources