Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #12731 > unrolled thread
| Started by | "analyst41@hotmail.com" <analyst41@hotmail.com> |
|---|---|
| First post | 2011-11-04 15:07 -0700 |
| Last post | 2011-11-11 15:44 +0000 |
| Articles | 20 on this page of 30 — 11 participants |
Back to article view | Back to comp.lang.c
newby question on C I/O "analyst41@hotmail.com" <analyst41@hotmail.com> - 2011-11-04 15:07 -0700
Re: newby question on C I/O Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-04 20:50 -0400
Re: newby question on C I/O "analyst41@hotmail.com" <analyst41@hotmail.com> - 2011-11-04 18:57 -0700
Re: newby question on C I/O "analyst41@hotmail.com" <analyst41@hotmail.com> - 2011-11-07 17:10 -0800
Re: newby question on C I/O Ian Collins <ian-news@hotmail.com> - 2011-11-08 14:47 +1300
Re: newby question on C I/O "BartC" <bc@freeuk.com> - 2011-11-08 01:52 +0000
Re: newby question on C I/O Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-07 20:56 -0500
Re: newby question on C I/O Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2011-11-08 20:27 +0000
Re: newby question on C I/O Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-08 20:48 -0500
Re: newby question on C I/O "BartC" <bc@freeuk.com> - 2011-11-09 11:12 +0000
Re: newby question on C I/O James Kuyper <jameskuyper@verizon.net> - 2011-11-09 07:02 -0500
Re: newby question on C I/O Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-11-09 16:12 +0000
Re: newby question on C I/O - SUCCESS "analyst41@hotmail.com" <analyst41@hotmail.com> - 2011-11-08 16:12 -0800
Re: newby question on C I/O James Kuyper <jameskuyper@verizon.net> - 2011-11-04 21:46 -0400
Re: newby question on C I/O Ike Naar <ike@iceland.freeshell.org> - 2011-11-05 06:52 +0000
Re: newby question on C I/O Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-11-05 04:13 -0700
Re: newby question on C I/O James Kuyper <jameskuyper@verizon.net> - 2011-11-05 08:16 -0400
Re: newby question on C I/O Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-05 09:21 -0400
Re: newby question on C I/O Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-05 09:13 -0400
Re: newby question on C I/O David Thompson <dave.thompson2@verizon.net> - 2011-11-21 02:39 -0500
Re: newby question on C I/O James Kuyper <jameskuyper@verizon.net> - 2011-11-21 10:05 -0500
Re: newby question on C I/O David Thompson <dave.thompson2@verizon.net> - 2012-01-19 02:40 -0500
Re: newby question on C I/O "BartC" <bc@freeuk.com> - 2011-11-06 21:23 +0000
Re: newby question on C I/O "analyst41@hotmail.com" <analyst41@hotmail.com> - 2011-11-10 18:00 -0800
Re: newby question on C I/O Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-11-11 01:35 -0800
Re: newby question on C I/O gazelle@shell.xmission.com (Kenny McCormack) - 2011-11-11 11:26 +0000
Re: newby question on C I/O Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-11-11 04:41 -0800
Re: newby question on C I/O gazelle@shell.xmission.com (Kenny McCormack) - 2011-11-11 14:14 +0000
Re: newby question on C I/O Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-11-11 07:02 -0800
Re: newby question on C I/O gazelle@shell.xmission.com (Kenny McCormack) - 2011-11-11 15:44 +0000
Page 1 of 2 [1] 2 Next page →
| From | "analyst41@hotmail.com" <analyst41@hotmail.com> |
|---|---|
| Date | 2011-11-04 15:07 -0700 |
| Subject | newby question on C I/O |
| Message-ID | <0f0ee88e-09f4-43ca-8c95-84f9a4846455@c1g2000vbw.googlegroups.com> |
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
subroutine getdat(values,costs,statuses.items)
character statuses*3
real values,costs
dimension values(1000),Costs(1000),Statuses(1000)
integer items, j
open (unit=1,file="filename")
read (1,*)
j = 0
do
j = j + 1
read (1,*,end=100) values(j),costs(j),statuses(j)
enddo
100 continue
items = j - 1
stop
end
Seems much harder in C - can anyone post an intuitive, easy solution
to do this in C?
Thanks.
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-11-04 20:50 -0400 |
| Message-ID | <j9217v$t4r$1@dont-email.me> |
| In reply to | #12731 |
On 11/4/2011 6:07 PM, analyst41@hotmail.com wrote:
> 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 ...)
> integer items, j
>
> open (unit=1,file="filename")
>
> read (1,*)
>
> j = 0
> do
> j = j + 1
> read (1,*,end=100) values(j),costs(j),statuses(j)
> enddo
>
> 100 continue
>
> items = j - 1
>
> stop
> end
>
> 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
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | "analyst41@hotmail.com" <analyst41@hotmail.com> |
|---|---|
| Date | 2011-11-04 18:57 -0700 |
| Message-ID | <bf7992bb-c409-4912-8053-c0fdf7e13664@r2g2000vbj.googlegroups.com> |
| In reply to | #12747 |
On Nov 4, 8:50 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 11/4/2011 6:07 PM, analys...@hotmail.com wrote:
>
> > 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 ...)
>
>
>
>
>
> > integer items, j
>
> > open (unit=1,file="filename")
>
> > read (1,*)
>
> > j = 0
> > do
> > j = j + 1
> > read (1,*,end=100) values(j),costs(j),statuses(j)
> > enddo
>
> > 100 continue
>
> > items = j - 1
>
> > stop
> > end
>
> > 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
> esos...@ieee-dot-org.invalid- Hide quoted text -
>
> - Show quoted text -
How weird, you want a WORRKING code :-)
OK then, if you insist.
> cat data.txt
value cost premium_status
23.0 43 Yes
23 23.3 no
43 60 yes
> cat fortranreader.f95
program main
parameter (maxrows = 10)
real values,costs
character*3 statuses
dimension values(maxrows),costs(maxrows),statuses(1000)
integer items,j
call getdat(values,costs,statuses,items)
do j = 1,items
print *,values(j),costs(j),trim(statuses(j))
enddo
! Do something with the data
stop
end
subroutine getdat(values,costs,statuses,items)
parameter (maxrows = 10)
real values,costs
character*3 statuses
dimension values(maxrows),costs(maxrows),statuses(1000)
integer items,j
open (unit=1,file = 'data.txt')
read (1,*)
do j = 1,maxrows
read (1,*,end=100) values(j),costs(j),statuses(j)
enddo
100 continue
items = j - 1
return
end
> a.out
23.000000 43.000000 Yes
23.000000 23.299999 no
43.000000 60.000000 yes
I am going to type your code in and see what it does. But the working
fortran shows what I want to do with the C (reason is that I have to
call a C library with the data).
[toc] | [prev] | [next] | [standalone]
| From | "analyst41@hotmail.com" <analyst41@hotmail.com> |
|---|---|
| Date | 2011-11-07 17:10 -0800 |
| Message-ID | <ebe91406-a5b0-4b9e-a5df-ebee60b16047@w7g2000yqc.googlegroups.com> |
| In reply to | #12747 |
On Nov 4, 7:50 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 11/4/2011 6:07 PM, analys...@hotmail.com wrote:
>
> > I have a file that looks like
>
> > Value Cost Special_Status
OK I typed the code in. The compiler complained about the character
field and I changed it to integer (1=yes, 0 = no).
#include <stdio.h>
#include <stdlib.h>
void getdat(float values[], float costs[], int statuses[], int
items) ;
void main()
{
float values[100], costs[100];
int statuses[100];
int items;
getdat(values, costs, statuses, items );
printf ("%d\n",items);
int j;
for (j = 0; j < items; ++j)
printf ("%10f\n",values[j]);
}
void getdat(float values[], float costs[], int statuses[],
int items)
{
int j;
char buffer[200]; /* big enough for a line */
FILE *unit = fopen("data.txt", "r");
fgets(buffer, sizeof buffer, unit); /* read 1st line */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%d", &items);
for (j = 0; j < items; ++j)
{
/* note that C arrays are 0-based */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%f%f%d", &values[j], &costs[j],
&statuses[j]);
}
/*
for (j = 0; j < items; ++j)
printf( "%3d %10f %10f %5d \n", j, values[j],
costs[j], statuses[j]);
*/
return;
/* exit(EXIT_SUCCESS); */
}
I also put the number of rows in row 2 (not being able to read till
EOF in C and counting the number of rows read)
I can verify from the function that it is working correctly; But I am
not able to use what was read in main.
All I get as output is
-1217507340
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-11-08 14:47 +1300 |
| Message-ID | <9hrg25F4bgU3@mid.individual.net> |
| In reply to | #12862 |
On 11/ 8/11 02:10 PM, analyst41@hotmail.com wrote:
> On Nov 4, 7:50 pm, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>> On 11/4/2011 6:07 PM, analys...@hotmail.com wrote:
>>
>>> I have a file that looks like
>>
>>> Value Cost Special_Status
>
> OK I typed the code in. The compiler complained about the character
> field and I changed it to integer (1=yes, 0 = no).
>
> #include<stdio.h>
> #include<stdlib.h>
>
> void getdat(float values[], float costs[], int statuses[], int
> items) ;
> void main()
Are you taking the Mickey?
> {
>
> float values[100], costs[100];
> int statuses[100];
> int items;
>
> getdat(values, costs, statuses, items );
>
>
> printf ("%d\n",items);
You never initialise or assign a value to items.
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-11-08 01:52 +0000 |
| Message-ID | <j9a220$hmc$1@dont-email.me> |
| In reply to | #12862 |
<analyst41@hotmail.com> wrote in message
news:ebe91406-a5b0-4b9e-a5df-ebee60b16047@w7g2000yqc.googlegroups.com...
> OK I typed the code in. The compiler complained about the character
> field and I changed it to integer (1=yes, 0 = no).
> int items;
>
> getdat(values, costs, statuses, items );
> All I get as output is
>
> -1217507340
Try this version:
I've changed the way 'items' is used (I assume you want getdat() to store
the number of items read into it):
#include <stdio.h>
#include <stdlib.h>
void getdat(float values[], float costs[], int statuses[], int*
items) ;
int main(void) {
float values[100], costs[100];
int statuses[100];
int items;
getdat(values, costs, statuses, &items );
printf ("%d\n",items);
int j;
for (j = 0; j < items; ++j)
printf ("%10f\n",values[j]);
}
void getdat(float values[], float costs[], int statuses[],
int* items)
{
int j;
char buffer[200]; /* big enough for a line */
FILE *unit = fopen("data.txt", "r");
fgets(buffer, sizeof buffer, unit); /* read 1st line */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%d", items);
for (j = 0; j < *items; ++j)
{
/* note that C arrays are 0-based */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%f%f%d", &values[j], &costs[j],
&statuses[j]);
}
/*
for (j = 0; j < items; ++j)
printf( "%3d %10f %10f %5d \n", j, values[j],
costs[j], statuses[j]);
*/
return;
/* exit(EXIT_SUCCESS); */
}
I still don't think it's right however..
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-11-07 20:56 -0500 |
| Message-ID | <j9a2a0$isv$1@dont-email.me> |
| In reply to | #12862 |
On 11/7/2011 8:10 PM, analyst41@hotmail.com wrote:
> On Nov 4, 7:50 pm, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>> On 11/4/2011 6:07 PM, analys...@hotmail.com wrote:
>>
>>> I have a file that looks like
>>
>>> Value Cost Special_Status
>
> OK I typed the code in. The compiler complained about the character
> field and I changed it to integer (1=yes, 0 = no).
Sorry: My blunder. I should have written just `costs[j]', not
`&costs[j]'.
> #include<stdio.h>
> #include<stdlib.h>
>
> void getdat(float values[], float costs[], int statuses[], int
> items) ;
> void main()
Oh, Lordy, Lordy, Lordy, will you ever catch flak for this!
>[...]
> I also put the number of rows in row 2 (not being able to read till
> EOF in C and counting the number of rows read)
Certainly you can do that, and it's easy. But I couldn't read
your Fortran-ized FORTRAN, so you've got to cut me some slack: I was
only guessing at what your Fortroid code was doing.
> I can verify from the function that it is working correctly; But I am
> not able to use what was read in main.
> [...]
Yeah. Well. Did you read my description of the code I supplied?
Did you see the adjective "TERRIBLE?" Did you comprehend that it was
only the barest of a bare-bones sketch, not suitable for actual use in
battlefield conditions? And did you go ahead and use it anyhow???
Some might say that you will never get anywhere by copying code
verbatim without trying to understand it. They're wrong: You will, in
fact, get somewhere. Somewhere unpleasant.
C is a powerful tool, but a tool without finger guards, without
kickback arrestors, without deadman switches. If Fortran has accustomed
you to such safeguards (FORTRAN would not have), be warned that you are
in mortal peril. Do Not, repeat, Do Not attempt to write C without
learning the language first; you are in danger and may put others there.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> |
|---|---|
| Date | 2011-11-08 20:27 +0000 |
| Message-ID | <j9c3an$u4f$1@speranza.aioe.org> |
| In reply to | #12867 |
Eric Sosman wrote: > On 11/7/2011 8:10 PM, analyst41@hotmail.com wrote: >> On Nov 4, 7:50 pm, Eric Sosman<esos...@ieee-dot-org.invalid> wrote: >>> On 11/4/2011 6:07 PM, analys...@hotmail.com wrote: >>> >>>> I have a file that looks like >>> >>>> Value Cost Special_Status >> >> OK I typed the code in. The compiler complained about the character >> field and I changed it to integer (1=yes, 0 = no). > > Sorry: My blunder. I should have written just `costs[j]', not > `&costs[j]'. > >> #include<stdio.h> >> #include<stdlib.h> >> >> void getdat(float values[], float costs[], int statuses[], int >> items) ; >> void main() > > Oh, Lordy, Lordy, Lordy, will you ever catch flak for this! > >>[...] >> I also put the number of rows in row 2 (not being able to read till EOF >> in C and counting the number of rows read) > > Certainly you can do that, and it's easy. But I couldn't read > your Fortran-ized FORTRAN, so you've got to cut me some slack: I was > only guessing at what your Fortroid code was doing. It looks to me as if your Fortran knowledge may be sorely out of date, Eric. Lower-case keywords have been standard Fortran since 1990. Heck, FORTRAN didn't even have dynamic memory allocation! You should come out of the stone age - it's pretty nice here in the 21st century :D
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-11-08 20:48 -0500 |
| Message-ID | <j9cm6t$hnv$1@dont-email.me> |
| In reply to | #12907 |
On 11/8/2011 3:27 PM, Edward Rutherford wrote:
> [...]
> It looks to me as if your Fortran knowledge may be sorely out of date,
> Eric. Lower-case keywords have been standard Fortran since 1990. Heck,
> FORTRAN didn't even have dynamic memory allocation!
I said as much in my first response. I last wrote FORTRAN in,
let's see, probably 1979 or thereabouts.
> You should come out of the stone age - it's pretty nice here in the 21st
> century :D
I'm progressing satisfactorily, thanks. I've given up wearing
uncured reindeer hides, and I've found adequate substitutes for my
old flint knives. I no longer suffer from scurvy in wintertime --
and I no longer write FORTRAN. Nor PL/1, for that matter, nor BASIC
nor SNOBOL nor BAL nor TAL. Nor object-oriented COOBOOL.
But seriously: My main point is that the O.P. should not have
imagined that the denizens of a Language X forum would be expert in
Language Y, nor that a snippet of Language Y code would be helpful
in explaining his difficulty. If he'd asked "What's the C equivalent
of x[⍋x←6?40]" he'd have made the same mistake -- and he'd have gotten
the same kind of "If it means what I think it means, then ..." replies.
Remember Babel.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-11-09 11:12 +0000 |
| Message-ID | <j9dn99$jn8$1@dont-email.me> |
| In reply to | #12907 |
"Edward Rutherford" <edward.p.rutherford79@REMOVETHIS.gmail.com> wrote in message news:j9c3an$u4f$1@speranza.aioe.org... > Eric Sosman wrote: >> Certainly you can do that, and it's easy. But I couldn't read >> your Fortran-ized FORTRAN, so you've got to cut me some slack: I was >> only guessing at what your Fortroid code was doing. > > It looks to me as if your Fortran knowledge may be sorely out of date, > Eric. Lower-case keywords have been standard Fortran since 1990. Heck, > FORTRAN didn't even have dynamic memory allocation! Let's look at part of what was posted: > subroutine getdat(values,costs,statuses.items) > > character statuses*3 > real values,costs > dimension values(1000),Costs(1000),Statuses(1000) > > integer items, j It wasn't so much the shock of seeing lower case keywords, but seeing identifiers written as costs and Costs, and status and Statuses, for no good reason, especially when declared over two statements instead of one; could this Fortran be case-sensitive and they are actually intended to be two separate identifers? There is values(1000), but maybe that was supposed to be Values(1000)? (You could just declare real values(1000), costs(1000) surely?) And then there is statuses.items, which may or may not be a typo. And the 9 spaces before 'subroutine', and the 8 before 'character'. With such an untidy bit of code, it's not surprising that they were doubts about it being valid Fortran, of any vintage. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-09 07:02 -0500 |
| Message-ID | <j9dq4j$4bl$1@dont-email.me> |
| In reply to | #12950 |
On 11/09/2011 06:12 AM, BartC wrote: > "Edward Rutherford" <edward.p.rutherford79@REMOVETHIS.gmail.com> wrote in > message news:j9c3an$u4f$1@speranza.aioe.org... ... > Let's look at part of what was posted: > >> subroutine getdat(values,costs,statuses.items) >> >> character statuses*3 >> real values,costs >> dimension values(1000),Costs(1000),Statuses(1000) >> >> integer items, j > > It wasn't so much the shock of seeing lower case keywords, but seeing > identifiers written as costs and Costs, and status and Statuses, for no good > reason, especially when declared over two statements instead of one; could > this Fortran be case-sensitive and they are actually intended to be two > separate identifers? There is values(1000), > but maybe that was supposed to be Values(1000)? > > (You could just declare real values(1000), costs(1000) surely?) > > And then there is statuses.items, which may or may not be a typo. And the 9 > spaces before 'subroutine', and the 8 before 'character'. > > With such an untidy bit of code, it's not surprising that they were doubts > about it being valid Fortran, of any vintage. Every constraint implied by your comments has been lifted; I believe that some of them may have been lifted before some current Fortran programmers were born. The last time I wrote Fortran on a regular basis was two decades ago, using VMS Fortran, and the only feature you've mentioned that seems new to me is statuses.items. I know little about modern Fortran, but enough to know that it is not a typo, and that it has a meaning similar to what it would mean in C. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-11-09 16:12 +0000 |
| Message-ID | <0.3871fee4e3a9d8fa08e4.20111109161207GMT.87ehxh2s2w.fsf@bsb.me.uk> |
| In reply to | #12956 |
James Kuyper <jameskuyper@verizon.net> writes: > On 11/09/2011 06:12 AM, BartC wrote: [nothing quoted from BartC but the reply refers to "you"] >> "Edward Rutherford" <edward.p.rutherford79@REMOVETHIS.gmail.com> wrote in >> message news:j9c3an$u4f$1@speranza.aioe.org... > ... >> Let's look at part of what was posted: >> >>> subroutine getdat(values,costs,statuses.items) >>> >>> character statuses*3 >>> real values,costs >>> dimension values(1000),Costs(1000),Statuses(1000) >>> >>> integer items, j <snip> > the only feature you've > mentioned that seems new to me is statuses.items. I know little about > modern Fortran, but enough to know that it is not a typo, and that it > has a meaning similar to what it would mean in C. I don't know of any similar meaning in C. The code looks like a subroutine declaration to me. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | "analyst41@hotmail.com" <analyst41@hotmail.com> |
|---|---|
| Date | 2011-11-08 16:12 -0800 |
| Subject | Re: newby question on C I/O - SUCCESS |
| Message-ID | <6207301b-860b-4464-99b8-5e770c7c0690@e2g2000vbb.googlegroups.com> |
| In reply to | #12867 |
On Nov 7, 8:56 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 11/7/2011 8:10 PM, analys...@hotmail.com wrote:
>
> > On Nov 4, 7:50 pm, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
> >> On 11/4/2011 6:07 PM, analys...@hotmail.com wrote:
>
> >>> I have a file that looks like
>
> >>> Value Cost Special_Status
>
>> --
> Eric Sosman
> esos...@ieee-dot-org.invalid
Thanks to all who responded. I figured it out from the posted code
and comments. My first foray into C coding reminds me of how we used
to do JCL back in the mainframe days - you go to the old guy who had
been around forever and get working JCL from him and and just change
data set names.
#include <stdio.h>
#include <stdlib.h>
void getdat(float bounds[], float values[], float costs[],
float statuses[], int* items) ;
void main()
{
float bounds[100], costs[100], values[100], statuses[100];
int items;
getdat(bounds, costs, values, statuses, &items );
printf ("%d\n",items);
int j;
for (j = 0; j < items; ++j)
printf ("%10f %10f %10f %10f \n", bounds[j], costs[j],
values[j],
statuses[j]);
}
void getdat(float bounds[], float costs[], float values[], float
statuses[],
int* items)
{
int j;
char buffer[200]; /* big enough for a line */
FILE *unit = fopen("sourcelp.txt", "r");
fgets(buffer, sizeof buffer, unit); /* read 1st line */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%d", items);
for (j = 0; j < *items; ++j)
{
/* note that C arrays are 0-based */
fgets(buffer, sizeof buffer, unit);
sscanf(buffer, "%f%f%f%f", &bounds[j], &values[j],
&costs[j],
&statuses[j]);
}
/*
for (j = 0; j < *items; ++j)
printf( "%3d %10f %10f %5d \n", j, values[j],
costs[j], statuses[j]);
*/
return;
/* exit(EXIT_SUCCESS); */
}
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-04 21:46 -0400 |
| Message-ID | <j924gs$d7s$1@dont-email.me> |
| In reply to | #12731 |
On 11/04/2011 06:07 PM, analyst41@hotmail.com wrote:
> 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
>
> subroutine getdat(values,costs,statuses.items)
>
> character statuses*3
> real values,costs
> dimension values(1000),Costs(1000),Statuses(1000)
>
> integer items, j
>
> open (unit=1,file="filename")
>
> read (1,*)
>
> j = 0
> do
> j = j + 1
> read (1,*,end=100) values(j),costs(j),statuses(j)
The '*' in that READ statement, where a FORMAT would ordinarily go,
indicates implicit formatting. A key difference between C and Fortran is
that I/O is a built-in part of the Fortran language, while in C I/O is
handled by standard library functions. Given the way C functions work,
that means that something equivalent to the implicit formatting used by
the READ statement above isn't feasible in C. The simplest approach
would be to use fscanf():
FILE *infile = fopen("filename", "r");
if(infile)
{
int j = 0;
while(fscanf(infile, "%f%f%3s\n",
values[j], costs[j], statuses[j]) == 3)
{
// process the line of data
j++;
}
if(ferror(infile)
{
// Error handling.
}
else
{
// Reached end of file.
}
if(fclose(infile))
{ // File couldn't be closed
// error handling
}
}
else
{ // File couldn't be opened
// error handling
}
I tried to keep this code simple, so it's can be compared to your
Fortran. I added only a little more error handling than is present in
your code. However, by my standards, this code is still less than ideal,
because it doesn't behave well in the face of format errors in the input
file.
If any line contains a number too big to be represented as a floating
point value, the behavior of fscanf() is undefined. If one of the
numbers is incorrectly formatted, the error detection capabilities of
this approach are limited. If any line contains too many fields, or too
few, the remaining lines in the file will be parsed incorrectly, because
fscanf() doesn't attach any special significant to new lines; they're
just whitespace, equivalent to tabs or spaces. I'm not sufficiently
familiar with the Fortran READ statement to be sure, but I suspect that
many of those issues would be equally problematic for your Fortran code.
I would use fgets() to fill in a line buffer, so I can process the data
one line at a time, checking for the possibility that the line being
read in is longer than the buffer. Format errors on one line won't carry
over to other lines.
I've only recently learned how to avoid the undefined behavior when the
numbers are too big, by using strtod(). It's more complicated to use
than fscanf("%f"), but it provides much better detection of possible
input errors.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2011-11-05 06:52 +0000 |
| Message-ID | <slrn3vfsjb9na4.b8e.ike@iceland.freeshell.org> |
| In reply to | #12749 |
On 2011-11-05, James Kuyper <jameskuyper@verizon.net> wrote: > while(fscanf(infile, "%f%f%3s\n", > values[j], costs[j], statuses[j]) == 3) The infamous scanf trap :-) &values[j], &costs[j], statuses[j]) == 3) Just curious: is the trailing "\n" in the fscanf format useful, or would the behaviour be the same if it were omitted?
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2011-11-05 04:13 -0700 |
| Message-ID | <cfa0d334-eae6-44c8-9d33-297dfb08ede8@hj4g2000vbb.googlegroups.com> |
| In reply to | #12765 |
On Nov 5, 8:52 am, Ike Naar <i...@iceland.freeshell.org> wrote: > > Just curious: is the trailing "\n" in the fscanf format useful, > or would the behaviour be the same if it were omitted? > Whitespace matches whitespace. It's better to out a newline rather than a space, because it indicates to a reader what you expect, but from the program's point of view it makes no difference. This is a flaw in fscanf(). It's a very old function, and in the light of thirty year's experience we'd specify it a bit differently if it was new. -- Basic Algorithms - how to do 3D games http://www.malcolmmclean.site11.com/www
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-11-05 08:16 -0400 |
| Message-ID | <j939f2$l41$1@dont-email.me> |
| In reply to | #12765 |
On 11/05/2011 02:52 AM, Ike Naar wrote: > On 2011-11-05, James Kuyper <jameskuyper@verizon.net> wrote: >> while(fscanf(infile, "%f%f%3s\n", >> values[j], costs[j], statuses[j]) == 3) > > The infamous scanf trap :-) > > &values[j], &costs[j], statuses[j]) == 3) Sorry for the mistake. I don't use fscanf() very often, and not just because of the problems I mentioned with out-of-range numeric values. For the last 15 years, most of the files my programs read are in HDF-EOS format, which they read using third-party library functions. Most of the rest are in CCSDS Production Data Se format, which they read using fread(). > Just curious: is the trailing "\n" in the fscanf format useful, > or would the behaviour be the same if it were omitted? I remember reaching the conclusion, a decade or two ago, that it did have some useful effect, but I can't find support for that concept by reading the standard's description of fscanf(). I believe I was assuming that a white-space directive requires the presence of at least one corresponding character of white-space, but I can't find explicit wording to that effect. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-11-05 09:21 -0400 |
| Message-ID | <j93dan$ath$1@dont-email.me> |
| In reply to | #12772 |
On 11/5/2011 8:16 AM, James Kuyper wrote:
> On 11/05/2011 02:52 AM, Ike Naar wrote:
>> On 2011-11-05, James Kuyper<jameskuyper@verizon.net> wrote:
>>> while(fscanf(infile, "%f%f%3s\n",
>>> values[j], costs[j], statuses[j]) == 3)
>>
>> The infamous scanf trap :-)
>>
>> &values[j],&costs[j], statuses[j]) == 3)
>
> Sorry for the mistake. I don't use fscanf() very often, and not just
> because of the problems I mentioned with out-of-range numeric values.
> For the last 15 years, most of the files my programs read are in HDF-EOS
> format, which they read using third-party library functions. Most of the
> rest are in CCSDS Production Data Se format, which they read using fread().
>
>> Just curious: is the trailing "\n" in the fscanf format useful,
>> or would the behaviour be the same if it were omitted?
>
> I remember reaching the conclusion, a decade or two ago, that it did
> have some useful effect, but I can't find support for that concept by
> reading the standard's description of fscanf(). I believe I was assuming
> that a white-space directive requires the presence of at least one
> corresponding character of white-space, but I can't find explicit
> wording to that effect.
A single white space character in the format string matches any
number of white space characters in the input, including zero. All
that matters is the whiteness: '\n' will gobble '\n', but also '\t'
and '\r' and '\v' and '\f' and ' ', and perhaps other locale-specific
spaces, in solid runs or in combinations.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-11-05 09:13 -0400 |
| Message-ID | <j93cqk$75o$1@dont-email.me> |
| In reply to | #12765 |
On 11/5/2011 2:52 AM, Ike Naar wrote:
> On 2011-11-05, James Kuyper<jameskuyper@verizon.net> wrote:
>> while(fscanf(infile, "%f%f%3s\n",
>> values[j], costs[j], statuses[j]) == 3)
>
> The infamous scanf trap :-)
>
> &values[j],&costs[j], statuses[j]) == 3)
>
> Just curious: is the trailing "\n" in the fscanf format useful,
> or would the behaviour be the same if it were omitted?
It's "useful" if the intended "use" is to convert three
items and then gobble all the whitespace that follows, on the
current and all subsequent lines. If '\n' were omitted the
behavior would change: There'd be no post-conversion gobbling.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2011-11-21 02:39 -0500 |
| Message-ID | <lptjc7tivkqh5ohopo9ie1tc2rrkoqul9a@4ax.com> |
| In reply to | #12749 |
On Fri, 04 Nov 2011 21:46:03 -0400, James Kuyper
<jameskuyper@verizon.net> wrote:
> On 11/04/2011 06:07 PM, analyst41@hotmail.com wrote:
> > 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
<snip>
> > read (1,*,end=100) values(j),costs(j),statuses(j)
>
> The '*' in that READ statement, where a FORMAT would ordinarily go,
> indicates implicit formatting. A key difference between C and Fortran is
Yes. Formally called 'list-directed' formatting.
> that I/O is a built-in part of the Fortran language, while in C I/O is
> handled by standard library functions. Given the way C functions work,
> that means that something equivalent to the implicit formatting used by
> the READ statement above isn't feasible in C. The simplest approach
Well, the syntax is a little different, but so is C stdio vs Fortran
classic explicit-format. Functionally, what Fortran list-directed
input does is a little different from what Standard C *scanf does, so
you would have to write maybe a page or two of code to fullly handle
it, which you could put in a utility function and reuse as needed.
OTOH, if you want Fortran input, using Fortran is usually easier. On
practically all systems you can do I/O in Fortran and call C, or
nearly always vice versa. The syntax is standardized in F>=03; before
that it had to be an extension and varied some.
> would be to use fscanf():
<snip>
> while(fscanf(infile, "%f%f%3s\n",
> values[j], costs[j], statuses[j]) == 3)
Missing &s already noted.
<snip rest>
> I tried to keep this code simple, so it's can be compared to your
> Fortran. I added only a little more error handling than is present in
> your code. However, by my standards, this code is still less than ideal,
> because it doesn't behave well in the face of format errors in the input
> file.
>
> If any line contains a number too big to be represented as a floating
> point value, the behavior of fscanf() is undefined. If one of the
In principle, although in practice this particular UB is usually not
bad. Especially for floating-point (as this case is).
> numbers is incorrectly formatted, the error detection capabilities of
> this approach are limited. If any line contains too many fields, or too
Format error detection is adequate; correction is lacking.
> few, the remaining lines in the file will be parsed incorrectly, because
> fscanf() doesn't attach any special significant to new lines; they're
> just whitespace, equivalent to tabs or spaces. I'm not sufficiently
> familiar with the Fortran READ statement to be sure, but I suspect that
> many of those issues would be equally problematic for your Fortran code.
>
The Fortran standard requires well-defined handling of whatever the
implementation classifies as an error condition (set iostat or goto
label cleanly or abort cleanly) but it doesn't say format error or
out-of-range is so classified. A *decent* implementation will do so
(and then, conformingly, handle them correctly).
The standard does define that too few values advance to the next line
(or you can use a terminator mark but the OP didn't) and too many
values (possibly after advancing) are ignored (unless you use
nonadvancing or stream, which the OP didn't).
> I would use fgets() to fill in a line buffer, so I can process the data
> one line at a time, checking for the possibility that the line being
> read in is longer than the buffer. Format errors on one line won't carry
> over to other lines.
>
Yep, for input that is actually line-oriented that's usually best.
> I've only recently learned how to avoid the undefined behavior when the
> numbers are too big, by using strtod(). It's more complicated to use
> than fscanf("%f"), but it provides much better detection of possible
> input errors.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web