Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #12731 > unrolled thread

newby question on C I/O

Started by"analyst41@hotmail.com" <analyst41@hotmail.com>
First post2011-11-04 15:07 -0700
Last post2011-11-11 15:44 +0000
Articles 20 on this page of 30 — 11 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#12731 — newby question on C I/O

From"analyst41@hotmail.com" <analyst41@hotmail.com>
Date2011-11-04 15:07 -0700
Subjectnewby 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]


#12747

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#12751

From"analyst41@hotmail.com" <analyst41@hotmail.com>
Date2011-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]


#12862

From"analyst41@hotmail.com" <analyst41@hotmail.com>
Date2011-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]


#12865

FromIan Collins <ian-news@hotmail.com>
Date2011-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]


#12866

From"BartC" <bc@freeuk.com>
Date2011-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]


#12867

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#12907

FromEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
Date2011-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]


#12938

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#12950

From"BartC" <bc@freeuk.com>
Date2011-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]


#12956

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-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]


#12970

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-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]


#12934 — Re: newby question on C I/O - SUCCESS

From"analyst41@hotmail.com" <analyst41@hotmail.com>
Date2011-11-08 16:12 -0800
SubjectRe: 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]


#12749

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-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]


#12765

FromIke Naar <ike@iceland.freeshell.org>
Date2011-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]


#12769

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2011-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]


#12772

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-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]


#12775

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#12774

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#13683

FromDavid Thompson <dave.thompson2@verizon.net>
Date2011-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