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


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

Text Files

Started byG B <gb@gb.com>
First post2018-02-14 11:47 -0400
Last post2018-02-25 20:12 +0000
Articles 20 on this page of 168 — 30 participants

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


Contents

  Text Files G B <gb@gb.com> - 2018-02-14 11:47 -0400
    Re: Text Files Ed Prochak <edprochak@gmail.com> - 2018-02-14 08:45 -0800
    Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-14 08:47 -0800
      Re: Text Files already5chosen@yahoo.com - 2018-02-15 01:17 -0800
    Re: Text Files gordonb.ea2mq@burditt.org (Gordon Burditt) - 2018-02-14 11:10 -0600
    Re: Text Files "James R. Kuyper" <jameskuyper@verizon.net> - 2018-02-14 12:28 -0500
    Re: Text Files jt@toerring.de (Jens Thoms Toerring) - 2018-02-14 21:07 +0000
    Re: Text Files Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2018-02-14 15:31 -0700
      Re: Text Files Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-02-15 06:59 +0000
        Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 10:20 +0000
    Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-14 22:51 +0000
      Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-15 11:04 +0100
        Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-15 06:16 -0800
          Re: Text Files "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2018-02-15 22:22 +0800
          Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-15 15:58 +0100
            Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 16:31 +0000
              Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-15 21:31 +0100
                Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 21:21 +0000
                  Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 22:17 +0000
                    Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 23:36 +0000
                      Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 23:48 +0000
                  Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 10:09 +0100
                    Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 12:57 +0000
                      Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 15:50 +0100
                        Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 15:50 +0000
                          Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 17:07 +0100
                            Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 20:44 +0000
                              Re: Text Files Ian Collins <ian-news@hotmail.com> - 2018-02-17 11:22 +1300
                          Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 17:48 +0000
                        Re: Text Files GOTHIER Nathan <nathan.gothier@gmail.com> - 2018-02-16 17:06 +0100
                      Re: Text Files Ian Collins <ian-news@hotmail.com> - 2018-02-17 11:10 +1300
                      Re: Text Files supercat@casperkitty.com - 2018-02-16 14:48 -0800
                        Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-16 15:14 -0800
                          Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 23:25 +0000
                          Re: Text Files supercat@casperkitty.com - 2018-02-16 15:50 -0800
            Re: Text Files already5chosen@yahoo.com - 2018-02-16 07:19 -0800
              Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 17:13 +0100
                Re: Text Files Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-02-19 17:55 +0000
                  Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-19 19:14 +0100
                  Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-19 11:48 -0800
              Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-16 08:14 -0800
                Re: Text Files Robert Wessel <robertwessel2@yahoo.com> - 2018-02-17 18:32 -0600
      Re: Text Files jacobnavia <jacob@jacob.remcomp.fr> - 2018-02-15 22:57 +0100
        Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 22:58 +0000
          Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 00:19 +0000
            Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 02:26 +0000
              Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 02:57 +0000
                Re: Text Files asetofsymbols@gmail.com - 2018-02-16 00:21 -0800
                  Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 11:30 +0000
            Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 10:36 +0100
              Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 11:36 +0000
                Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 13:10 +0100
                  Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 12:25 +0000
                    Re: Text Files Ike Naar <ike@iceland.freeshell.org> - 2018-03-06 19:33 +0000
                      Re: Text Files bartc <bc@freeuk.com> - 2018-03-06 20:55 +0000
                  Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-16 04:42 -0800
                    Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 16:58 +0100
                      Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 20:02 +0000
                        Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 21:43 +0100
                      Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-17 04:01 -0800
                        Re: Text Files bartc <bc@freeuk.com> - 2018-02-17 13:10 +0000
                          Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-17 05:27 -0800
                            Re: Text Files bartc <bc@freeuk.com> - 2018-02-17 14:20 +0000
                    Re: Text Files Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2018-02-16 09:04 -0700
                  Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 14:31 +0000
                    Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-16 06:42 -0800
                      Re: Text Files bartc <bc@freeuk.com> - 2018-02-16 14:58 +0000
                        Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-16 07:23 -0800
                      Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-16 15:24 +0000
                Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-16 04:13 -0800
                  Re: Text Files Siri Cruise <chine.bleu@yahoo.com> - 2018-02-16 04:29 -0800
                    Re: Text Files Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-02-20 16:41 +0000
                      Re: Text Files Siri Cruise <chine.bleu@yahoo.com> - 2018-02-20 09:39 -0800
                        Re: Text Files Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-02-20 19:16 +0000
    Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 12:46 +0000
      Re: Text Files GOTHIER Nathan <nathan.gothier@gmail.com> - 2018-02-15 14:52 +0100
      Re: Text Files Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-02-15 17:07 +0300
        Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 14:23 +0000
          Re: Text Files Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-02-15 18:52 +0300
      Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 14:39 +0000
        Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 15:43 +0000
          Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 20:32 +0000
            Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 22:06 +0000
              Re: Text Files GOTHIER Nathan <nathan.gothier@gmail.com> - 2018-02-15 23:12 +0100
              Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-15 15:12 -0800
                Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 23:43 +0000
                  Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 23:54 +0000
              Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 23:35 +0000
            Re: Text Files Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-16 17:07 -0800
              Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-17 02:38 +0000
                Re: Text Files Ian Collins <ian-news@hotmail.com> - 2018-02-17 17:26 +1300
                  Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-17 11:22 +0000
                  Re: Text Files bartc <bc@freeuk.com> - 2018-02-17 12:07 +0000
                    Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-17 04:17 -0800
                      Re: Text Files Anton Shepelev <anton.txt@gmail.com> - 2018-02-17 16:25 +0300
                        Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-17 07:35 -0800
                      Re: Text Files GOTHIER Nathan <nathan.gothier@gmail.com> - 2018-02-17 15:24 +0100
                    Re: Text Files Ian Collins <ian-news@hotmail.com> - 2018-02-18 11:10 +1300
                Re: Text Files Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-19 12:05 -0800
                  Re: Text Files already5chosen@yahoo.com - 2018-02-19 15:32 -0800
                    Re: Text Files Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 10:34 -0800
                      Re: Text Files already5chosen@yahoo.com - 2018-02-21 15:35 -0800
                        Re: Text Files bartc <bc@freeuk.com> - 2018-02-22 00:11 +0000
                      Re: Text Files Robert Wessel <robertwessel2@yahoo.com> - 2018-02-21 18:26 -0600
                        Re: Text Files Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 21:39 -0800
                          Re: Text Files Robert Wessel <robertwessel2@yahoo.com> - 2018-02-23 03:08 -0600
                            Re: Text Files supercat@casperkitty.com - 2018-02-23 16:16 -0800
                              Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-23 16:46 -0800
                                Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-24 02:49 -0800
                                  Re: Text Files asetofsymbols@gmail.com - 2018-02-24 05:16 -0800
                                    Re: Text Files "F. Russell" <fr@random.info> - 2018-02-24 14:35 +0000
                                      Re: Text Files Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2018-02-24 08:48 -0700
                                Re: Text Files supercat@casperkitty.com - 2018-02-25 15:09 -0800
                                  Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-25 15:54 -0800
                                    Re: Text Files supercat@casperkitty.com - 2018-02-26 11:04 -0800
                                      Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-26 11:52 -0800
                                    Re: Text Files supercat@casperkitty.com - 2018-02-26 14:12 -0800
                                      Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-26 14:40 -0800
                        Re: Text Files already5chosen@yahoo.com - 2018-02-22 04:58 -0800
                          Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-22 05:33 -0800
                          Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-22 13:59 +0000
                            Re: Text Files Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2018-02-22 07:24 -0800
                Re: Text Files supercat@casperkitty.com - 2018-02-20 12:14 -0800
          Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-15 21:37 +0100
            Re: Text Files bartc <bc@freeuk.com> - 2018-02-15 21:34 +0000
              Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-15 14:15 -0800
              Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-16 10:47 +0100
    Re: Text Files "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2018-02-15 22:20 +0800
    Re: Text Files "F. Russell" <fr@random.info> - 2018-02-15 15:24 +0000
      Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-15 16:05 +0000
      Re: Text Files "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2018-02-16 00:22 +0800
      Re: Text Files Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2018-02-15 13:35 -0700
    Re: Text Files Anton Shepelev <anton.txt@gmail.com> - 2018-02-25 00:13 +0300
      Re: Text Files bartc <bc@freeuk.com> - 2018-02-24 21:24 +0000
        Re: Text Files Anton Shepelev <anton.txt@gmail.com> - 2018-02-25 14:55 +0300
          Re: Text Files bartc <bc@freeuk.com> - 2018-02-25 13:00 +0000
      Re: Text Files Real Troll <Real.Troll@Trolls.com> - 2018-02-24 17:35 -0400
      Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-24 21:36 +0000
        Re: Text Files Real Troll <Real.Troll@Trolls.com> - 2018-02-24 17:45 -0400
        Re: Text Files Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-02-24 22:51 +0000
          Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-24 23:56 +0000
            Re: Text Files bartc <bc@freeuk.com> - 2018-02-25 00:14 +0000
              Re: Text Files bartc <bc@freeuk.com> - 2018-02-25 00:22 +0000
              Re: Text Files Anton Shepelev <anton.txt@gmail.com> - 2018-02-25 15:16 +0300
                Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-25 15:20 -0800
                  Re: Text Files Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2018-02-25 20:27 -0700
                  Re: Text Files gazelle@shell.xmission.com (Kenny McCormack) - 2018-02-26 06:19 +0000
                  Re: Text Files Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-02-26 15:35 +0300
                    Re: Text Files Reinhardt Behm <rbehm@hushmail.com> - 2018-02-26 20:53 +0800
                      Grammar Patrol (Was: Text Files) gazelle@shell.xmission.com (Kenny McCormack) - 2018-02-26 17:54 +0000
                    Re: Text Files Jorgen Grahn <grahn+nntp@snipabacken.se> - 2018-02-26 15:27 +0000
                      Re: Text Files Anton Shepelev <anton.txt@g{oogle}mail.com> - 2018-02-26 18:50 +0300
                        Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-26 09:26 -0800
                          Re: Text Files scott@slp53.sl.home (Scott Lurndal) - 2018-02-26 19:46 +0000
                          Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-27 09:04 +0100
                            Re: Text Files already5chosen@yahoo.com - 2018-02-27 00:56 -0800
                              Re: Text Files Ian Collins <ian-news@hotmail.com> - 2018-02-27 22:07 +1300
                                Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-27 14:37 +0100
                                  Re: Text Files already5chosen@yahoo.com - 2018-02-27 07:38 -0800
                                    Re: Text Files supercat@casperkitty.com - 2018-02-27 09:18 -0800
                              Re: Text Files David Brown <david.brown@hesbynett.no> - 2018-02-27 10:15 +0100
                              Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-27 08:53 -0800
                        Re: Text Files Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-26 23:14 -0800
                    Re: Text Files Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2018-02-26 08:32 -0700
                    Re: Text Files Keith Thompson <kst-u@mib.org> - 2018-02-26 09:17 -0800
                    Re: Text Files Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-26 22:55 -0800
        Re: Text Files Anton Shepelev <anton.txt@gmail.com> - 2018-02-25 15:02 +0300
          Re: Text Files Ben Bacarisse <ben.usenet@bsb.me.uk> - 2018-02-25 20:12 +0000

Page 5 of 9 — ← Prev page 1 2 3 4 [5] 6 7 8 9  Next page →


#126733

Frombartc <bc@freeuk.com>
Date2018-02-15 15:43 +0000
Message-ID<oUhhC.249883$w26.130771@fx47.am4>
In reply to#126728
On 15/02/2018 14:39, Ben Bacarisse wrote:
> bartc <bc@freeuk.com> writes:

>> Here's my C coding exercise for the morning. It uses a library-based
>> approach: put all the fiddly details into functions, in the aim of
>> keeping the main function as simple and as close to the above as
>> possible.

> But more importantly the OP probably wants to see the C way of doing it
> rather trying to shoe-horn C into what is probably just an illustrative
> example.

I don't think the OP is enough of a beginner not to know how to apply an 
array to this example.

>> Any extra specification, error checking etc can also be added to the
>> functions as needed, without affecting the use of the line- and
>> number-reading code too much. (For example checking for overlong
>> lines, or having an expanding buffer, or dealing with input
>> errors. Note that as written, it can only read from one file at a
>> time, as the linebuffer etc is local to readline().)
> 
> Yes, you do no error checking and yet the program is way more
> complicated than it needs to be.

Is it? The main() function is about 20 lines, little more than yours, 
and that's partly because I don't use an array for the six variables to 
keep it in line with the OP's.

The rest are reusable library functions: read the next line from a file 
(without the fiddly details of directly calling fgets), and consuming 
elements from the line just read, of which readint() is one possibility.

   I can't shake the feeling you are
> doing this to further your agenda of making C look more complicated than
> it is.

Perhaps people can compare my code with yours, and they can decide for 
themselves which is more complicated.

> Why use int64_t?

That's the maximum easily usable integer size in C. The main program 
only uses 32 bit ints; yes the library elements are more general than 
this one specific application of them.

> If you wanted a more
> general readint function then long long is the type to use since it is
> guaranteed to be available, is at least 64 bits wide, and matches the
> type of strtoll.

That's an interesting remark coming from you, as your code fragments 
generally make use of complicated features such as VLAs, variable types 
(those multi-dimensional types in parameters), designated initialisers, 
wide strings, compound literals and generics. [None of which my C 
compiler supports!]

But int64_t is a simple typedef if not available.

> What is the eof member of Buffpos for?  And without , is there any
> reason to have a struct at all?

Yes, the struct is a placeholder to put other stuff in. It helps offset 
the confusion of a pointer to pointer.

The .eof member is an error return from readline(), which is optional if 
ateof() is used.


> Why do your signature EOF dance when you should know by now that C
> favours a "try it and see if worked" model of IO?

You mean C's 'keep walking until you've fallen off the edge of the 
cliff' idiom, rather than my 'if not at the edge of the cliff, take 
another step'? (Of course ateof() has to fall off the edge to make it 
work - fortunately you can step back up - but that logic is confined to 
that function.)

> Why limit the program to reading one named file?  This seems to be thing
> with Windows C programmers.

That's a limitation I saw after I finished. I left it in as the 
intention was not to provide a perfect implementation, but to show how 
the code can be structured.

(And solving it introduces another complication. Note that my scripting 
language also shares a single line buffer across files, for this kind of 
reading. I've never known it to be a problem.)

> Does the development environment make it
> hard to run a program with stdin coming from a file?  If so, then surely
> having the name of the input file in argv is the way to go.

No, it just introduced a complication that was not necessary. The OP's 
example didn't show where infile came from, and they can find out about 
argv from elsewhere. To use stdin, they can do fh=stdin, but this is 
stuff we've discussed countless times. It's not that relevant here.

> #include <stdio.h>
> #include <stdbool.h>
> 
> bool parse_line(const char *lp, size_t n_wanted, int *d)
> {
>       int n, len;
>       size_t n_read = 0;
>       while (sscanf(lp, "%d %n", &n, &len) == 1) {
>            if (n_read < n_wanted)
>                 d[n_read] = n;
>            n_read += 1;
>            lp += len + (lp[len] == ',' || lp[len] == ';');
>       }
>       return *lp == 0 && n_read == n_wanted;
> }
> 
> int main(void)
> {
>       char line[1000];
>       size_t lnum = 0, numbers_per_line = 6;
>       int data[numbers_per_line];
> 
>       while (fgets(line, sizeof line, stdin)) {
>            lnum += 1;
>            if (parse_line(line, numbers_per_line, data)) {
>                 for (size_t i = 0; i < numbers_per_line; i++)
>                      printf(" %5d", data[i]);
>                 putchar('\n');
>            }
>            else fprintf(stderr, "Bad input on line %zu\n", lnum);
>       }
> }

I thought at last, I can run one of Ben's examples with my compiler. But 
it says, 'Can't do VLAs'! I needed to change numbers_per_line to an enum.

Note that on error, your program says 'Bad input on line zu'.

And you have a go at me for using 'int64_t'!

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#126750

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-02-15 20:32 +0000
Message-ID<87a7wa8040.fsf@bsb.me.uk>
In reply to#126733
bartc <bc@freeuk.com> writes:

> On 15/02/2018 14:39, Ben Bacarisse wrote:
>> bartc <bc@freeuk.com> writes:
>
>>> Here's my C coding exercise for the morning. It uses a library-based
>>> approach: put all the fiddly details into functions, in the aim of
>>> keeping the main function as simple and as close to the above as
>>> possible.
>
>> But more importantly the OP probably wants to see the C way of doing it
>> rather trying to shoe-horn C into what is probably just an illustrative
>> example.
>
> I don't think the OP is enough of a beginner not to know how to apply
> an array to this example.

That comment was about the forced IO style, not about using an array.

>>   I can't shake the feeling you are
>> doing this to further your agenda of making C look more complicated than
>> it is.
>
> Perhaps people can compare my code with yours, and they can decide for
> themselves which is more complicated.

That's why I posted it.  As I said, I'm sure there are plenty of people
who won't like it.  Maybe we can get a version from some of them.  It's
always good to see lots of versions.

>> Why use int64_t?
>
> That's the maximum easily usable integer size in C.

No it's not.  There is such a type (intmax_t) but even using that would
miss the point.

> The main program only uses 32 bit ints;

No, it uses ints.

> yes the library elements are
> more general than this one specific application of them.
>
>> If you wanted a more
>> general readint function then long long is the type to use since it is
>> guaranteed to be available, is at least 64 bits wide, and matches the
>> type of strtoll.
>
> That's an interesting remark coming from you, as your code fragments
> generally make use of complicated features such as VLAs, variable
> types (those multi-dimensional types in parameters), designated
> initialisers, wide strings, compound literals and generics. [None of
> which my C compiler supports!]

Eh?  I am not against using any particular feature of the language.
When you need a 64-bit 2's complement signed int, int64_t is the way to
go.  But here I just can't see why you want to over-specify the type
when you can't do any better than use long long -- if long long int is
wider than 64-bits you'll get into trouble with some conversions, and if
it's narrower than 64-bits you won't be able to actually read a 64-bit
as the function appears to promise (from the type).

> But int64_t is a simple typedef if not available.

If int64_t is not available on a conforming implementation it can't be
made available by a typedef.

>> Why do your signature EOF dance when you should know by now that C
>> favours a "try it and see if worked" model of IO?
>
> You mean C's 'keep walking until you've fallen off the edge of the
> cliff' idiom, rather than my 'if not at the edge of the cliff, take
> another step'?

No.  I meant what I said.  C's style of IO does not involve any peril as
your humorous re-write suggests.  It's simply a better way to do input. 

>> #include <stdio.h>
>> #include <stdbool.h>
>>
>> bool parse_line(const char *lp, size_t n_wanted, int *d)
>> {
>>       int n, len;
>>       size_t n_read = 0;
>>       while (sscanf(lp, "%d %n", &n, &len) == 1) {
>>            if (n_read < n_wanted)
>>                 d[n_read] = n;
>>            n_read += 1;
>>            lp += len + (lp[len] == ',' || lp[len] == ';');
>>       }
>>       return *lp == 0 && n_read == n_wanted;
>> }
>>
>> int main(void)
>> {
>>       char line[1000];
>>       size_t lnum = 0, numbers_per_line = 6;
>>       int data[numbers_per_line];
>>
>>       while (fgets(line, sizeof line, stdin)) {
>>            lnum += 1;
>>            if (parse_line(line, numbers_per_line, data)) {
>>                 for (size_t i = 0; i < numbers_per_line; i++)
>>                      printf(" %5d", data[i]);
>>                 putchar('\n');
>>            }
>>            else fprintf(stderr, "Bad input on line %zu\n", lnum);
>>       }
>> }
>
> I thought at last, I can run one of Ben's examples with my
> compiler. But it says, 'Can't do VLAs'! I needed to change
> numbers_per_line to an enum.

If a post looks like probable coursework I try to put "talking points"
into it.  If a student copies it, the instructor can ask things like
"show me where you use a VLA", "explain the space in the sscanf
format" and "what does %zu mean in that printf?".

> Note that on error, your program says 'Bad input on line zu'.

Not for me.  Something is probably wrong at your end.

> And you have a go at me for using 'int64_t'!

Yes, for the reasons I explained which are not because it's "new", or
"fancy" but because it's not the best type to use where you used it.
You'd have a point if I'd complained about using some new-fang led thing
like VLAs (which have not been around for two decades yet), but I didn't
do that.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#126759

Frombartc <bc@freeuk.com>
Date2018-02-15 22:06 +0000
Message-ID<KvnhC.23431$3X6.19280@fx22.am4>
In reply to#126750
On 15/02/2018 20:32, Ben Bacarisse wrote:
> bartc <bc@freeuk.com> writes:

>> But int64_t is a simple typedef if not available.
> 
> If int64_t is not available on a conforming implementation it can't be
> made available by a typedef.

Why, what's wrong with writing:

    typedef long long int int64_t;

I don't like 'long long int' because it's ungainly. And trying to make 
it less so with 'long long' looks sloppy. (Actually I only use it if 
it's less effort than sticking '#include <stdint.h>' at the top.)

Anyway this is all to do with the quality of the implementation of the 
'library' code I'd written. It's purposefully at a certain standard, and 
was just to illustrate an approach.

You can rewrite the library, and the chances are the main() function 
will stay the same. Unless you change the interface.

>>> bool parse_line(const char *lp, size_t n_wanted, int *d)
>>> {
>>>        int n, len;
>>>        size_t n_read = 0;
>>>        while (sscanf(lp, "%d %n", &n, &len) == 1) {
>>>             if (n_read < n_wanted)
>>>                  d[n_read] = n;
>>>             n_read += 1;
>>>             lp += len + (lp[len] == ',' || lp[len] == ';');
>>>        }
>>>        return *lp == 0 && n_read == n_wanted;
>>> }

Your code does look gorgeous though. (If not very clear.)

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#126760

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2018-02-15 23:12 +0100
Message-ID<20180215231230.608f5c8269a7a85e409ef1da@gmail.com>
In reply to#126759
On Thu, 15 Feb 2018 22:06:48 +0000
bartc <bc@freeuk.com> wrote:

> Why, what's wrong with writing:
> 
>     typedef long long int int64_t;

It's wrong because it should be:

  typedef long long int_least64_t;


> I don't like 'long long int' because it's ungainly. And trying to
> make it less so with 'long long' looks sloppy. (Actually I only use
> it if it's less effort than sticking '#include <stdint.h>' at the
> top.)

Or you can just do:

  typedef long long llong_t;

-- 
GOTHIER Nathan

[toc] | [prev] | [next] | [standalone]


#126764

FromKeith Thompson <kst-u@mib.org>
Date2018-02-15 15:12 -0800
Message-ID<lnwozdonjx.fsf@kst-u.example.com>
In reply to#126759
bartc <bc@freeuk.com> writes:
> On 15/02/2018 20:32, Ben Bacarisse wrote:
>> bartc <bc@freeuk.com> writes:
>>> But int64_t is a simple typedef if not available.
>> 
>> If int64_t is not available on a conforming implementation it can't be
>> made available by a typedef.
>
> Why, what's wrong with writing:
>
>     typedef long long int int64_t;

The types long long int and int64_t were both introduced by C99.

A conforming C90 implementation won't provide long long int, so the
typedef will fail.  A conforming C99 or C11 implementation will almost
certainly provide int64_t in <stdint.h>, so the typedef is unnecessary.

If a *conforming* C implementation doesn't provide int64_t, it's because
it can't, perhaps because it has no 64-bit integer types (long long int
can legally be wider than 64 bits), or because it has padding bits, or
because it doesn't use a two's complement representation.

I might define my own int64_t typedef *if* it's for use with a
non-conforming implementation that doesn't provide it, and I'm trying to
mimic some of the standard library that the implementation fails to
support.  I would avoid using the name "int64_t" if the implementation
provides it correctly, or if it's for a type that doesn't meet the
standard's requirements for that type.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#126767

Frombartc <bc@freeuk.com>
Date2018-02-15 23:43 +0000
Message-ID<qWohC.33281$6B6.9501@fx17.am4>
In reply to#126764
On 15/02/2018 23:12, Keith Thompson wrote:
> bartc <bc@freeuk.com> writes:
>> On 15/02/2018 20:32, Ben Bacarisse wrote:
>>> bartc <bc@freeuk.com> writes:
>>>> But int64_t is a simple typedef if not available.
>>>
>>> If int64_t is not available on a conforming implementation it can't be
>>> made available by a typedef.
>>
>> Why, what's wrong with writing:
>>
>>      typedef long long int int64_t;
> 
> The types long long int and int64_t were both introduced by C99.
> 
> A conforming C90 implementation won't provide long long int, so the
> typedef will fail.

Ben said that 'long long' is guaranteed to be available.

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#126769

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-02-15 23:54 +0000
Message-ID<87606x7qr1.fsf@bsb.me.uk>
In reply to#126767
bartc <bc@freeuk.com> writes:

> On 15/02/2018 23:12, Keith Thompson wrote:
>> bartc <bc@freeuk.com> writes:
>>> On 15/02/2018 20:32, Ben Bacarisse wrote:
>>>> bartc <bc@freeuk.com> writes:
>>>>> But int64_t is a simple typedef if not available.
>>>>
>>>> If int64_t is not available on a conforming implementation it can't be
>>>> made available by a typedef.
>>>
>>> Why, what's wrong with writing:
>>>
>>>      typedef long long int int64_t;
>>
>> The types long long int and int64_t were both introduced by C99.
>>
>> A conforming C90 implementation won't provide long long int, so the
>> typedef will fail.
>
> Ben said that 'long long' is guaranteed to be available.

Not in C90.  The remark was made as a comment to you your original code
where you used int64_t.  I meant it is guaranteed to be available as an
alternative to int64_t.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#126765

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-02-15 23:35 +0000
Message-ID<87h8qh7rnm.fsf@bsb.me.uk>
In reply to#126759
bartc <bc@freeuk.com> writes:

> On 15/02/2018 20:32, Ben Bacarisse wrote:
>> bartc <bc@freeuk.com> writes:
>
>>> But int64_t is a simple typedef if not available.
>>
>> If int64_t is not available on a conforming implementation it can't be
>> made available by a typedef.
>
> Why, what's wrong with writing:
>
>    typedef long long int int64_t;

Keith has explained this better that I could, so I'll leave it.

>>>> bool parse_line(const char *lp, size_t n_wanted, int *d)
>>>> {
>>>>        int n, len;
>>>>        size_t n_read = 0;
>>>>        while (sscanf(lp, "%d %n", &n, &len) == 1) {
>>>>             if (n_read < n_wanted)
>>>>                  d[n_read] = n;
>>>>             n_read += 1;
>>>>             lp += len + (lp[len] == ',' || lp[len] == ';');
>>>>        }
>>>>        return *lp == 0 && n_read == n_wanted;
>>>> }
>
> Your code does look gorgeous though. (If not very clear.)

That's very magnanimous of you to say so.  Thanks.

It's an odd style.  It came about from teaching programming (and not
just in C).  It can, in that environment, be important to get everything
that matters onto one slide, in as large a font as you can get away
with, so I avoid extraneous lines and write things that are more compact
that one would write in other environments.[1]

And having code that causes students to stop and think, even as it is
being explained or talked about, is no bad thing.  This is one reason
why I don't care about writing

  lp += len + (lp[len] == ',' || lp[len] == ';');

which would not pass many code reviews, I think.  But for a student (and
this is not a dissimilar environment) it can be a positive advantage to
cause a second (or even third) take.

[1] I can write the other sort of C -- the sort that passes code reviews
and conforms to dull house styles, but I don't have to anymore so I
generally don't.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#126822

FromTim Rentsch <txr@alumni.caltech.edu>
Date2018-02-16 17:07 -0800
Message-ID<kfn8tbsxw3b.fsf@x-alumni2.alumni.caltech.edu>
In reply to#126750
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> bartc <bc@freeuk.com> writes:
>
>> [programs to read integers on a line]
>>
>> Perhaps people can compare my code with yours, and they can decide for
>> themselves which is more complicated.
>
> That's why I posted it.  As I said, I'm sure there are plenty of people
> who won't like it.  Maybe we can get a version from some of them.  It's
> always good to see lots of versions.

(Sorry to have misplaced the context of the earlier programs.. :()

I am contributing just a partial program.  I did write a whole
program, but the main loop was mostly just the same as yours.
What I have is a replacement for parse_line() (which I called
parse_one_line()), with just a slightly different interface - a
negative value means a parse error, non-negative means that's how
many items were read.  Here is the function:

signed
parse_one_line( const char *p, signed const K, signed data[ const K ] ){
    signed k, d, n;

    for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;  p+=n,  k++  ){
        if(  k < K  )  data[k] = d;
    }

    return  *p ? -1 : k;
}


(Disclaimer:  either I have Impostor Syndrome or I am not an
expert with the *scanf() functions.)

[toc] | [prev] | [next] | [standalone]


#126823

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-02-17 02:38 +0000
Message-ID<87y3jsz6fm.fsf@bsb.me.uk>
In reply to#126822
Tim Rentsch <txr@alumni.caltech.edu> writes:
<snip>
> signed
> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
>     signed k, d, n;
>
>     for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;  p+=n,  k++  ){
>         if(  k < K  )  data[k] = d;
>     }
>
>     return  *p ? -1 : k;
> }

As someone who has taken the scanf red pill I think that's nice, but it
does present a bigger target for the naysayers.

It's a real shame that scanf's number conversions were not defined on
overflow.  I say that never having had to implement it that way, so
there may be a reason why it is onerous to require it.  As things stand,
the naysayers have the trump card with the behaviour on overflow.

That leads to it being less used, and then that leads to anything but the
simple numeric conversions being considered a black art.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#126825

FromIan Collins <ian-news@hotmail.com>
Date2018-02-17 17:26 +1300
Message-ID<fepp82Fhu2kU1@mid.individual.net>
In reply to#126823
On 02/17/2018 03:38 PM, Ben Bacarisse wrote:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
> <snip>
>> signed
>> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
>>      signed k, d, n;
>>
>>      for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;  p+=n,  k++  ){
>>          if(  k < K  )  data[k] = d;
>>      }
>>
>>      return  *p ? -1 : k;
>> }
> 
> As someone who has taken the scanf red pill I think that's nice, but it
> does present a bigger target for the naysayers.
> 
> It's a real shame that scanf's number conversions were not defined on
> overflow.  I say that never having had to implement it that way, so
> there may be a reason why it is onerous to require it.  As things stand,
> the naysayers have the trump card with the behaviour on overflow.
> 
> That leads to it being less used, and then that leads to anything but the
> simple numeric conversions being considered a black art.

One of the advantages of the much maligned C++ streaming paradigm is you 
can provide your own specialised types to take care of things like 
overflow or more general input range checking.

-- 
Ian

[toc] | [prev] | [next] | [standalone]


#126826

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2018-02-17 11:22 +0000
Message-ID<87sh9zzwqv.fsf@bsb.me.uk>
In reply to#126825
Ian Collins <ian-news@hotmail.com> writes:

> On 02/17/2018 03:38 PM, Ben Bacarisse wrote:
<snip>
>> It's a real shame that scanf's number conversions were not defined on
>> overflow.
<snip>
> One of the advantages of the much maligned C++ streaming paradigm is
> you can provide your own specialised types to take care of things like
> overflow or more general input range checking.

That made me go look at what happens by default but I could find the
full answers.  Probably lack of familiarity with the standard.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#126828

Frombartc <bc@freeuk.com>
Date2018-02-17 12:07 +0000
Message-ID<PVUhC.610145$w26.51757@fx47.am4>
In reply to#126825
On 17/02/2018 04:26, Ian Collins wrote:
> On 02/17/2018 03:38 PM, Ben Bacarisse wrote:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> <snip>
>>> signed
>>> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
>>>      signed k, d, n;
>>>
>>>      for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;  
>>> p+=n,  k++  ){
>>>          if(  k < K  )  data[k] = d;
>>>      }
>>>
>>>      return  *p ? -1 : k;
>>> }
>>
>> As someone who has taken the scanf red pill I think that's nice, but it
>> does present a bigger target for the naysayers.
>>
>> It's a real shame that scanf's number conversions were not defined on
>> overflow.  I say that never having had to implement it that way, so
>> there may be a reason why it is onerous to require it.  As things stand,
>> the naysayers have the trump card with the behaviour on overflow.
>>
>> That leads to it being less used, and then that leads to anything but the
>> simple numeric conversions being considered a black art.
> 
> One of the advantages of the much maligned C++ streaming paradigm is you 
> can provide your own specialised types to take care of things like 
> overflow or more general input range checking.

It can be done at C-level with a more tiered approach. But people insist 
on doing all the detailed work at the front line rather than abstracting 
it away. While this looks 'the business', no one really understands it 
confidently enough to make use of it.

At the lowest level, where the requirements are not strict, you can read 
ints, floats, names, strings etc along a line, similar to my demo of a 
few days ago. Equivalent to read a, b, c.

Or read every item as a name or string, and convert to a number as needed.

A simple approach for numbers is to encode any missing or error value as 
MININT or INFINITY, which can be picked up in the ordinary range 
checking you might do.

Anything more elaborate, you might need to grab the whole line and work 
on that (this is Python's starting point). Then you might also be 
looking at regular expressions (which I've never used) and formal 
tokenisers and parsers.

But ask yourself what is necessary to read the simplest kind of 
configuration text file. Having to switch to C++ or even employ an XML 
library really isn't. Why not keep things simple?

-- 
bartc

[toc] | [prev] | [next] | [standalone]


#126829

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2018-02-17 04:17 -0800
Message-ID<409d231d-35b7-4d56-9c64-5b1ca8211e78@googlegroups.com>
In reply to#126828
On Saturday, February 17, 2018 at 12:07:22 PM UTC, Bart wrote:
> 
> Anything more elaborate, you might need to grab the whole line and work 
> on that (this is Python's starting point). Then you might also be 
> looking at regular expressions (which I've never used) and formal 
> tokenisers and parsers.
> 
> But ask yourself what is necessary to read the simplest kind of 
> configuration text file. Having to switch to C++ or even employ an XML 
> library really isn't. Why not keep things simple?
> 
I wrote a "vanilla" XML parser for the Baby X resource compiler.

The resource scripts are meant to be fairly simple, just the
path to the file plus a few options, for example for image
resizing. But it was too complicated to do ad hoc in the main
file, whilst not complicated enough to justify taking in a monster
third party XML sub-module that would dominate the codebase.

But I had to write my own XML parser specially, which is not
ideal.

[toc] | [prev] | [next] | [standalone]


#126833

FromAnton Shepelev <anton.txt@gmail.com>
Date2018-02-17 16:25 +0300
Message-ID<20180217162516.97e69d228188b2e53877cfb4@gmail.com>
In reply to#126829
Malcolm McLean:

> I  wrote a "vanilla" XML parser for the Baby X re-
> source compiler.
>
> The resource scripts are meant to be  fairly  sim-
> ple, just the path to the file plus a few options,
> for example for image resizing.  But  it  was  too
> complicated  to do ad hoc in the main file, whilst
> not complicated enough to justify taking in a mon-
> ster  third  party XML sub-module that would domi-
> nate the codebase.

Is not XML itself too complicated for the task?  Why
not parse a simpler language, like:

<path>:
   <option1>=<value1>
   <option2>=<value2>
   ...
   <optionN>=<valueN>

Would not it be more in the spirit of BabyX?

-- 
()  ascii ribbon campaign -- against html e-mail
/\  http://preview.tinyurl.com/qcy6mjc [archived]

[toc] | [prev] | [next] | [standalone]


#126837

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2018-02-17 07:35 -0800
Message-ID<33dcaf2b-bad2-4ab1-a9d6-85895567233a@googlegroups.com>
In reply to#126833
On Saturday, February 17, 2018 at 1:25:25 PM UTC, Anton Shepelev wrote:
> Malcolm McLean:
> 
> > I  wrote a "vanilla" XML parser for the Baby X re-
> > source compiler.
> >
> > The resource scripts are meant to be  fairly  sim-
> > ple, just the path to the file plus a few options,
> > for example for image resizing.  But  it  was  too
> > complicated  to do ad hoc in the main file, whilst
> > not complicated enough to justify taking in a mon-
> > ster  third  party XML sub-module that would domi-
> > nate the codebase.
> 
> Is not XML itself too complicated for the task?  Why
> not parse a simpler language, like:
> 
> <path>:
>    <option1>=<value1>
>    <option2>=<value2>
>    ...
>    <optionN>=<valueN>
> 
> Would not it be more in the spirit of BabyX?
> 
In a way you're right. Of course a Baby X resource compiler script
uses only a subset of XML. But XML is familiar. I don't want the
user to have to learn a new scripting language just to get a few images
into Baby X.

[toc] | [prev] | [next] | [standalone]


#126836

FromGOTHIER Nathan <nathan.gothier@gmail.com>
Date2018-02-17 15:24 +0100
Message-ID<20180217152418.306fcf0e8fa6f7197661cdab@gmail.com>
In reply to#126829
On Sat, 17 Feb 2018 04:17:13 -0800 (PST)
Malcolm McLean <malcolm.arthur.mclean@gmail.com> wrote:

> I wrote a "vanilla" XML parser for the Baby X resource compiler.
> 
> The resource scripts are meant to be fairly simple, just the
> path to the file plus a few options, for example for image
> resizing. But it was too complicated to do ad hoc in the main
> file, whilst not complicated enough to justify taking in a monster
> third party XML sub-module that would dominate the codebase.
> 
> But I had to write my own XML parser specially, which is not
> ideal.

XML sucks by design. It is too generic and overcomplicated to be
useful. However, an XML-like application can be useful with a limited
scope.

-- 
GOTHIER Nathan

[toc] | [prev] | [next] | [standalone]


#126840

FromIan Collins <ian-news@hotmail.com>
Date2018-02-18 11:10 +1300
Message-ID<fernj1Fu6hlU1@mid.individual.net>
In reply to#126828
On 02/18/2018 01:07 AM, bartc wrote:
> On 17/02/2018 04:26, Ian Collins wrote:
>> On 02/17/2018 03:38 PM, Ben Bacarisse wrote:
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>> <snip>
>>>> signed
>>>> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
>>>>       signed k, d, n;
>>>>
>>>>       for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;
>>>> p+=n,  k++  ){
>>>>           if(  k < K  )  data[k] = d;
>>>>       }
>>>>
>>>>       return  *p ? -1 : k;
>>>> }
>>>
>>> As someone who has taken the scanf red pill I think that's nice, but it
>>> does present a bigger target for the naysayers.
>>>
>>> It's a real shame that scanf's number conversions were not defined on
>>> overflow.  I say that never having had to implement it that way, so
>>> there may be a reason why it is onerous to require it.  As things stand,
>>> the naysayers have the trump card with the behaviour on overflow.
>>>
>>> That leads to it being less used, and then that leads to anything but the
>>> simple numeric conversions being considered a black art.
>>
>> One of the advantages of the much maligned C++ streaming paradigm is you
>> can provide your own specialised types to take care of things like
>> overflow or more general input range checking.
> 
> It can be done at C-level with a more tiered approach. But people insist
> on doing all the detailed work at the front line rather than abstracting
> it away. While this looks 'the business', no one really understands it
> confidently enough to make use of it.

C's standard I/O makes abstraction difficult.  The C model is to provide 
a set of options to describe the expected input format.  While powerful 
(one you get your head around the details) this has a few drawbacks:

You can only specify format requirement (field widths and the like) but 
not data (ranges) requirements.

Error reporting is poor, you don't know why input parsing failed.

The C++ model allows user defined types to provide their own streaming 
operators which can perform on the spot error checking.  If the 
programmer chooses to throw an exception on checking failure, any code 
following the input can proceed knowing all of the read data is valid. 
If not, the code can check the data and if input checking had failed, 
determine why.

> At the lowest level, where the requirements are not strict, you can read
> ints, floats, names, strings etc along a line, similar to my demo of a
> few days ago. Equivalent to read a, b, c.
> 
> Or read every item as a name or string, and convert to a number as needed.
> 
> A simple approach for numbers is to encode any missing or error value as
> MININT or INFINITY, which can be picked up in the ordinary range
> checking you might do.
> 
> Anything more elaborate, you might need to grab the whole line and work
> on that (this is Python's starting point). Then you might also be
> looking at regular expressions (which I've never used) and formal
> tokenisers and parsers.
> 
> But ask yourself what is necessary to read the simplest kind of
> configuration text file. Having to switch to C++ or even employ an XML
> library really isn't. Why not keep things simple?

Simple is good, things get messy when the data isn't simple...

-- 
Ian.

[toc] | [prev] | [next] | [standalone]


#126859

FromTim Rentsch <txr@alumni.caltech.edu>
Date2018-02-19 12:05 -0800
Message-ID<kfnsh9wwxqx.fsf@x-alumni2.alumni.caltech.edu>
In reply to#126823
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Tim Rentsch <txr@alumni.caltech.edu> writes:
> <snip>
>
>> signed
>> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
>>     signed k, d, n;
>>
>>     for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;  p+=n,  k++  ){
>>         if(  k < K  )  data[k] = d;
>>     }
>>
>>     return  *p ? -1 : k;
>> }
>
> As someone who has taken the scanf red pill I think that's nice, but it
> does present a bigger target for the naysayers.
>
> It's a real shame that scanf's number conversions were not defined on
> overflow.  I say that never having had to implement it that way, so
> there may be a reason why it is onerous to require it.  As things stand,
> the naysayers have the trump card with the behaviour on overflow.

Detecting the out-of-range condition is easy.  The question is
how to handle it when it occurs.  The *scanf() functions aren't
like strtol() where only a single value is returned.  At a guess,
previous implementations made different choices, and rather than
trying to reconcile them the original standard just punted and
declared it undefined behavior.  And the rest, as they say, is
history.

For this particular problem though we can work around the problem
of out-of-range values, since the numbers being input are all
small:

signed
parse_one_line( const char *p, signed const K, signed data[ const K ] ){
    signed k, d;
    long long signed m, n;

    for(
        k = 0;
        sscanf( p, "%4d%lln %lln%*1[,;] %lln", &d, &m, &n, &n ) > 0  &&  m < n;
        k < K  ? data[k] = d  : 0,   p += n,   k++
    ){}

    return  *p ? -1 : k;
}

This function accepts non-negative values up to four digits,
which will never have a problem with the value not being able to
be represented in an int.  (In principle the %lln conversions can
overflow but they never will in our lifetimes.)  Values that
need more digits can use %ld or %lld, obviously.

> That leads to it being less used, and then that leads to anything but the
> simple numeric conversions being considered a black art.

Yeah.  Hopefully the example function above has put some more
weight on the good side of the scale.

[toc] | [prev] | [next] | [standalone]


#126869

Fromalready5chosen@yahoo.com
Date2018-02-19 15:32 -0800
Message-ID<fab9f170-dc1e-4f87-a5a4-c4370ad14880@googlegroups.com>
In reply to#126859
On Monday, February 19, 2018 at 10:06:10 PM UTC+2, Tim Rentsch wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> 
> > Tim Rentsch <txr@alumni.caltech.edu> writes:
> > <snip>
> >
> >> signed
> >> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
> >>     signed k, d, n;
> >>
> >>     for(  k=0;  sscanf( p, "%d %n%*1[,;] %n", &d, &n, &n ) > 0;  p+=n,  k++  ){
> >>         if(  k < K  )  data[k] = d;
> >>     }
> >>
> >>     return  *p ? -1 : k;
> >> }
> >
> > As someone who has taken the scanf red pill I think that's nice, but it
> > does present a bigger target for the naysayers.
> >
> > It's a real shame that scanf's number conversions were not defined on
> > overflow.  I say that never having had to implement it that way, so
> > there may be a reason why it is onerous to require it.  As things stand,
> > the naysayers have the trump card with the behaviour on overflow.
> 
> Detecting the out-of-range condition is easy.  The question is
> how to handle it when it occurs.  The *scanf() functions aren't
> like strtol() where only a single value is returned.  At a guess,
> previous implementations made different choices, and rather than
> trying to reconcile them the original standard just punted and
> declared it undefined behavior.  And the rest, as they say, is
> history.
> 
> For this particular problem though we can work around the problem
> of out-of-range values, since the numbers being input are all
> small:
> 
> signed
> parse_one_line( const char *p, signed const K, signed data[ const K ] ){
>     signed k, d;
>     long long signed m, n;
> 
>     for(
>         k = 0;
>         sscanf( p, "%4d%lln %lln%*1[,;] %lln", &d, &m, &n, &n ) > 0  &&  m < n;
>         k < K  ? data[k] = d  : 0,   p += n,   k++
>     ){}
> 
>     return  *p ? -1 : k;
> }
> 
> This function accepts non-negative values up to four digits,
> which will never have a problem with the value not being able to
> be represented in an int.  (In principle the %lln conversions can
> overflow but they never will in our lifetimes.)  Values that
> need more digits can use %ld or %lld, obviously.
> 
> > That leads to it being less used, and then that leads to anything but the
> > simple numeric conversions being considered a black art.
> 
> Yeah.  Hopefully the example function above has put some more
> weight on the good side of the scale.

Personally, with regard to sscanf() I am one of those naysayers mentioned above. Yes, sscanf is less evil than scanf/fscanf, but it is bad enough. Less The World uses it - the better.

[toc] | [prev] | [next] | [standalone]


Page 5 of 9 — ← Prev page 1 2 3 4 [5] 6 7 8 9  Next page →

Back to top | Article view | comp.lang.c


csiph-web