| Version 1.9 Build 1556
|
|
Next: Sample Application
Up: Introduction to Programming for AIPS++
Previous: An advanced example
The following code defines the two functions.
(The source code
for this program is found in
$AIPSROOT/code/trial/implement/test/tExample1.cc).
1 #include <aips/IO/AipsIO.h>
2 #include <aips/Arrays/ArrayIO.h>
3 #include <aips/Arrays/ArrayMath.h>
4 #include <aips/Containers/Block.h>
5 #include <aips/Inputs/Input.h>
6 #include <aips/Mathematics/Math.h>
7 #include <aips/Arrays/Matrix.h>
8 #include <aips/Arrays/Vector.h>
9 #include <iostream.h>
10 #include <fstream.h> // needed for file IO
11 #include <strstream.h> // needed for internal IO
12
13
14 template <class T>
15 void
16 ReadAsciiFile(const char *filein, Matrix<T> &mat)
17 {
18 const Int bufSize = 1024, numberSize = 50;
19 char buf[bufSize], buf2[numberSize];
20 uInt blockSize = 100;
21 Block<T> temp(blockSize);
22
23 ifstream iFile;
24 iFile.open(filein, ios::in);
25 if (! iFile) {
26 cerr << "Cannot open " << filein << "for reading\n"; exit (-1);}
27
28 Int rows = 0, cols = 0, saveCols = 0;
29 uInt havePoint = 0;
30
31 while (iFile.getline(buf, bufSize)) {
32 Int blankLine = 1;
33 for (Int j1=0;j1<bufSize;j1++) {
34 if (buf[j1] == '\0') break;
35 if (buf[j1] != ' ') {blankLine = 0; break;}
36 }
37
38 if (! blankLine) {
39 if (havePoint > (blockSize - saveCols - 10)) {
40 blockSize *= 2;
41 temp.resize(blockSize);
42 }
43
44 rows += 1; cols = 0;
45 Int ch = 0, startedNew = 0;
46 for (Int i2=0; i2<bufSize; i2++) {
47 if (buf[i2] == '\0' || buf[i2] == ' ') {
48 if (ch > 0) {
49 buf2[ch] = ' ';
50 istrstream(buf2,sizeof(buf2)) >> temp[havePoint];
51 havePoint += 1;
52 ch = 0;
53 }
54 startedNew = 0;
55 if (buf[i2] == '\0') break;
56 }
57
58 if (buf[i2] != ' ' && startedNew == 0) {
59 cols += 1;
60 startedNew = 1;
61 }
62
63 if (startedNew) buf2[ch++] = buf[i2];
64 }
65
66 if (rows == 1) saveCols = cols;
67 else if (cols != saveCols) {
68 cout << "Array is not regular. Number of elements was "
69 << saveCols << " at row 1"
70 << " but is " << cols << " at row " << rows << endl;
71 exit (1);
72 }
73 }
74 }
75 iFile.close();
76
77 mat.resize(rows, cols);
78 Int k3 = 0;
79 for (Int i3=0;i3<rows;i3++)
80 for (Int j3=0;j3<cols;j3++)
81 mat(i3,j3) = temp[k3++];
82
83 }
84
85
86 template <class T>
87 void
88 WriteAsciiFile(const char *fileout, Matrix<T> &mat)
89 {
90 Int rows, cols;
91
92 mat.shape(rows,cols);
93 ofstream oFile;
94 oFile.precision(12);
95 oFile.open(fileout, ios::out);
96 for (Int i1=0;i1<rows;i1++) {
97 for (Int j1=0;j1<cols;j1++) {
98 oFile << mat(i1,j1) << " ";
99 }
100 oFile << endl;
101 }
102 }
- 10-
- The inclusion of <fstream.h> code is used to handle the reading from
and writing to an external file.
- 11-
- The <strstream.h> is used to handle in-memory I/O
i.e. to read a string that is
already in memory (presumably to read it with a new format).
- 14-16-
- This is the function declaration. The first argument is prefixed with
the keyword const which tells the compiler that this argument is NOT to
be modified by the function code. Note that the type of data to be stored in
the Matrix is STILL undefined i.e. it is declared to be of whatever type
corresponds to the Matrix used in the calling sequence.
- 18-
- The dimension of the input string (each line of data) is stated as 1024.
A bit overgenerous perhaps, but what the heck!
- 19-
- Two arrays, buf and buf2 of type char are used as
described below.
- 20-
- The initial size of the Block that will first contain the values to be read
is stated here. Unlike previous examples it is NOT a const because we
might well need to increase its value during the operation of the routine.
- 21-
- A Block is used used to contain the values initially. This is used, rather
than a Matrix, because a Block can change size during the operation of a
routine without losing its current content. (And since we have no idea how
large a data set we need to read we must be able to expand.) A Matrix does
NOT have that ability. Note that the dimension of a Block is stated within a
FORTAN-like pair of parentheses rather than square brackets!
- 23-26-
- The ASCII file from which we want to read the data is opened.
If the file
cannot be opened for any reason the program will quit with an error
message.
- 28-
- The dimensions of the Matrix will be rows and cols whose values
will be determined by the input. Since we will
only deal with rectangular arrays, the variable saveCols will be used to
check that each row has the same number of columns.
- 29-
- The variable havePoint will keep track of how full the temp
Block is becoming. If the Block is becoming too full, it is expanded
(doubled) by
invoking the function resize (in lines 39-41).
- 31-
- Reads an input line of up to bufSize characters.
If there are no more lines go to the end of the
while statement at line 74.
- 32-36-
- Check for a completly blank input line. If one is found, the variable
blankLine will be left at the value 1 (TRUE) and it will be simply skipped
by the test on line 38.
- 39-
- The test for the Block becoming too small makes provision for 10 more than
the next row. If the line holds more values than that, then there are other
problems to worry about!
- 44-
- Each line read (which may contain as many as 1024 characters) is presumed
to contain a complete row.
- 45-
- The variable ch counts the characters in each new variable being
read from the input string. The variable startedNew will be FALSE while
we are bypassing
an indefinite number of blanks before each value.
- 46-
- Starts the loop to scan an input line.
- 47-56-
- Check to see if we are at the end of a line or at a blank. In either
case see if we have already picked up the characters for a new number. If so,
add a terminating blank to the new number then call the internal IO routine
to read it into a number in the temp array. Keep track of the number of
points read in this row. In any case set the flag to bypass any more
blanks on this line.
- 58-61-
- If we have encountered a character and we were skipping blanks set the
startedNew flag to TRUE.
- 63-
- If we are reading a new number, place the latest character on a string.
- 75-
- Close the input file.
- 77-
- Now we know the size of the array so go ahead and make the Matrix be the
appropriate size.
- 78-81-
- Transfer the data from the Block to the Matrix. NOTE the round
parentheses surrounding the Matrix subscripts but the square brackets around
the Block subscript! AAARGH!
- 86-88-
- This is declaring the second function, WriteAsciiFile.
- 92-
- Since we need to handle ANY shape, we need to recover the value of the
rows and cols variables.
- 93-
- Declare an ASCII ouput file.
- 94-
- Set the precision with which we want to record output values. (The default
is 6 digits.)
- 95-
- Open the output file.
- 96-98-
- Copy the Matrix to the output, placing one space between each value.
- 100-
- Terminate each output line with an EOL (end-of-line aka newline).
Next: Sample Application
Up: Introduction to Programming for AIPS++
Previous: An advanced example
  Contents
  Index
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc.,
Washington, D.C.
Return to AIPS++ Home Page
2006-10-15