I have a file that looks like
Value Cost Special_Status
12 34 Yes
21 44 yes
32 43 no
.....................
I can read it into some arrays (or a data frame using R) using Fortran
trivially
Hmmph. This isn't the FORTRAN I knew. But anyhow ...
subroutine getdat(values,costs,statuses.items)
I don't comprehend the "statuses.items" notation -- as I hinted,
my acquaintance with FORTRAN has been tenuous for the last few decades.
I'll proceed on the assumption that "." should have been ",".
character statuses*3
real values,costs
dimension values(1000),Costs(1000),Statuses(1000)
Is Fortran case-blind? FORTRAN knew only one letter case, but
most compilers would have been mightily confused by the difference
between 'C' and 'c' or 'S' and 's'. (I recall a little game we used
to play in school: The object was to produce an inexplicable listing
of a program and its output, and to post same as a puzzle. One of the
better hinged on the difference between 'C' and 'c', both of which
appeared as 'C' on the monocase printer, but only one of which was
recognized as "this introduces a comment." Coupled with a non-blank
but non-printing character in the "this line continues the previous"
position, this allowed something that looked like a comment in the
listing to be actual, executable code ...)
open (unit=1,file="filename")
j = 0
do
j = j + 1
read (1,*,end=100) values(j),costs(j),statuses(j)
enddo
Seems much harder in C - can anyone post an intuitive, easy solution
to do this in C?
#include <stdio.h>
#include <stdlib.h>
void getdat(float values[], float costs[],
char[][4] statuses, int items) {
char buffer[200]; /* big enough for a line */
FILE *unit = fopen("filename", "r");
fgets(buffer, sizeof buffer, unit); /* read 1st line */
for (int j = 0; j < items; ++j) {
/* note that C arrays are 0-based */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%f%f%s", &values[j], &costs[j],
&statuses[j]);
}
exit(EXIT_SUCCESS);
}
A couple notes: First, what I've provided is TERRIBLE code,
because it completely ignores the possibility of error: garbage in
the input, actual I/O errors, or anything else. I left it all out
because I don't know what your newfangled Fortran does in such cases
and thus don't know how to imitate it. In my day, FORTRAN had FORMAT
constructs, and there were fatal run-time errors if the input didn't
match the FORMAT.
Second, it would be simple to combine the fgets/sscanf pair into
a single fscanf call. If the absence of error-checking were acceptable
this would be a sensible thing to do. But when error-checking is added,
it will probably turn out to be useful to separate the physical I/O
(fgets) from the interpretation of the data (sscanf) instead of trying
to put them into one portmanteau (fscanf).
Third, both code snippets "leak" an open I/O stream. Since both
terminate the program that's probably not important; the operating
system's post-termination cleanup will probably dispose of them (in
C's case, "probably" becomes "definitely"). But if the eventual intent
is to do something more than just read and ignore all the data, you'd
want an fclose() call in C and an I-don't-know-what in Fortran.
Finally, I reiterate: I'm just guessing at what your Fortran does;
it seems to be some kind of mutant offspring of the FORTRAN I once knew,
and the genetic damage may extend to more than just appearance.
--
Eric Sosman
(e-mail address removed)- Hide quoted text -
- Show quoted text -