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


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

Program to read csv file, store characters and numbers in separate arrays

Started byAlla _ <modelling.data@gmail.com>
First post2016-12-15 05:05 -0800
Last post2016-12-16 11:46 +0000
Articles 20 on this page of 72 — 11 participants

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


Contents

  Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-15 05:05 -0800
    Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 13:48 +0000
      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-15 08:22 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 16:28 +0000
          Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-15 09:25 -0800
            Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 19:31 +0000
              Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 01:19 -0800
                Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 10:01 +0000
                  Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 02:43 -0800
                    Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 11:03 +0000
                      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 03:08 -0800
                        Re: Program to read csv file, store characters and numbers in separate arrays jameskuyper@verizon.net - 2016-12-18 03:32 -0800
                    Re: Program to read csv file, store characters and numbers in separate arrays Barry Schwarz <schwarzb@dqel.com> - 2016-12-16 17:09 -0800
              Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 01:25 -0800
                Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 10:11 +0000
                  Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 02:45 -0800
                    Re: Program to read csv file, store characters and numbers in separate arrays Keith Thompson <kst-u@mib.org> - 2016-12-16 09:54 -0800
                      Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 17:56 +0000
                      Re: Program to read csv file, store characters and numbers in separate arrays gazelle@shell.xmission.com (Kenny McCormack) - 2016-12-16 18:02 +0000
                  Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 03:06 -0800
                    Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 11:28 +0000
                      Re: Program to read csv file, store characters and numbers in separate arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-16 12:02 +0000
                        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 12:41 +0000
                          Re: Program to read csv file, store characters and numbers in separate arrays BartC <bc@freeuk.com> - 2016-12-16 13:40 +0000
                            Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 14:03 +0000
                        Re: Program to read csv file, store characters and numbers in separate arrays BartC <bc@freeuk.com> - 2016-12-16 13:03 +0000
                          Re: Program to read csv file, store characters and numbers in separate arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-16 15:04 +0000
                            Re: Program to read csv file, store characters and numbers in separate arrays BartC <bc@freeuk.com> - 2016-12-16 15:26 +0000
                              Re: Program to read csv file, store characters and numbers in separate arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-16 17:01 +0000
                      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 04:18 -0800
    Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 14:12 +0000
      Re: Program to read csv file, store characters and numbers in separate arrays David Brown <david.brown@hesbynett.no> - 2016-12-15 16:14 +0100
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 15:37 +0000
          Re: Program to read csv file, store characters and numbers in separate arrays David Brown <david.brown@hesbynett.no> - 2016-12-15 23:20 +0100
            Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 23:27 +0000
              Re: Program to read csv file, store characters and numbers in separate arrays David Brown <david.brown@hesbynett.no> - 2016-12-16 12:10 +0100
                Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 11:43 +0000
                  Re: Program to read csv file, store characters and numbers in separate arrays David Brown <david.brown@hesbynett.no> - 2016-12-16 14:01 +0100
                    Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 13:12 +0000
                      Re: Program to read csv file, store characters and numbers in separate arrays David Brown <david.brown@hesbynett.no> - 2016-12-16 14:57 +0100
        Re: Program to read csv file, store characters and numbers in separate arrays BartC <bc@freeuk.com> - 2016-12-15 16:30 +0000
          Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 16:36 +0000
            Re: Program to read csv file, store characters and numbers in separate arrays David Brown <david.brown@hesbynett.no> - 2016-12-15 23:29 +0100
      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-15 08:26 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 16:33 +0000
      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-15 08:32 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 16:37 +0000
        Re: Program to read csv file, store characters and numbers in separate arrays Keith Thompson <kst-u@mib.org> - 2016-12-15 12:17 -0800
          Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 01:33 -0800
      Re: Program to read csv file, store characters and numbers in separate arrays Keith Thompson <kst-u@mib.org> - 2016-12-15 12:23 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-15 20:39 +0000
      Re: Program to read csv file, store characters and numbers in separate arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-15 21:13 +0000
      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 00:39 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 08:54 +0000
          Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 01:09 -0800
            Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 09:32 +0000
              Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 01:51 -0800
                Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 10:08 +0000
                  Re: Program to read csv file, store characters and numbers in separate arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-16 11:09 +0000
                    Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 03:16 -0800
                      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 03:20 -0800
                        Re: Program to read csv file, store characters and numbers in separate arrays Keith Thompson <kst-u@mib.org> - 2016-12-16 09:48 -0800
                          Re: Program to read csv file, store characters and numbers in separate arrays gazelle@shell.xmission.com (Kenny McCormack) - 2016-12-16 17:55 +0000
                          Re: Program to read csv file, store characters and numbers in separate arrays raltbos@xs4all.nl (Richard Bos) - 2016-12-20 11:53 +0000
                    Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 11:33 +0000
              Re: Program to read csv file, store characters and numbers in separate arrays Keith Thompson <kst-u@mib.org> - 2016-12-16 09:46 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-03 15:38 -0500
    Re: Program to read csv file, store characters and numbers in separate arrays Barry Schwarz <schwarzb@dqel.com> - 2016-12-15 12:36 -0800
      Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 01:44 -0800
        Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 10:04 +0000
          Re: Program to read csv file, store characters and numbers in separate arrays Alla _ <modelling.data@gmail.com> - 2016-12-16 03:14 -0800
            Re: Program to read csv file, store characters and numbers in separate arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-16 11:46 +0000

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#99637

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-16 11:28 +0000
Message-ID<o30j33$8po$1@dont-email.me>
In reply to#99628
On 16/12/16 11:06, Alla _ wrote:
> On Friday, December 16, 2016 at 1:11:58 PM UTC+3, Richard Heathfield wrote:
>> On 16/12/16 09:25, Alla _ wrote:
>>> On Thursday, December 15, 2016 at 10:31:28 PM UTC+3, Richard Heathfield wrote:
>>>> On 15/12/16 17:25, Alla _ wrote:
> <snip>
>> Hex dump, please.
>>
> Below I post:
> (1) The corrected version of the program based on comments I have received;

I will make only one comment on the program, because I think first we 
need to sort out your data.

> (2) csv inputs
> (3) program's outputs
> (4) hex dumps for each csv
> Interesting: now that I have changed the error checking method, i.e. if (!ferror(fp)),
> instead of checking for !feof, I get the error message at the end of the whole output;
> this is telling me that there is something wrong with every csv file.

Yeah, your logic says:

IF there is NOT an error
   Report an error

Remove the !


>
> (2) File you have sent me (without changing Income
> statement to Years in the first row):
>
> ******csv file******
> Income Statement,2011,2012,2013,2014,2015

This is the line we care about, because:

> ******code output with one trailing zero******
> (3) 2011 2012 2013 2014 2015 0

...here is our first trailing zero. So let's look at the data up to that 
point, using a hex dump.

> ******hex******
> 49 6E 63 6F 6D 65 20 53 74 61 74 65 6D 65 6E 74
> 2C 32 30 31 31 2C 32 30 31 32 2C 32 30 31 33 2C
> 32 30 31 34 2C 32 30 31 35 0D 0A

There's your problem right there. 0D 0A instead of just 0A.

On Windows, 0D 0A is a correct line-end indicator. On Linux and on 
modern Macs, 0A is the right indicator. So your copy of Excel is 
preparing its CSV file for use on Windows, when it *should* be preparing 
it for use on the host system.

Here is a simple filter for you to use:

#include <stdio.h>
int main(void)
{
   int ch;
   while((ch = getchar()) != EOF)
   {
     if(ch != '\r')
     {
       putchar(ch);
     }
   }
   return 0;
}

Usage:

./dos2unix < input.csv > output.csv

Removes all carriage returns from the file.

You might already have a dos2unix program on your system, in which case 
by all means use that.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99641

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-16 12:02 +0000
Message-ID<87a8bw2iai.fsf@bsb.me.uk>
In reply to#99637
Richard Heathfield <rjh@cpax.org.uk> writes:
<snip>

> ...here is our first trailing zero. So let's look at the data up to
> that point, using a hex dump.
>
>> ******hex******
>> 49 6E 63 6F 6D 65 20 53 74 61 74 65 6D 65 6E 74
>> 2C 32 30 31 31 2C 32 30 31 32 2C 32 30 31 33 2C
>> 32 30 31 34 2C 32 30 31 35 0D 0A
>
> There's your problem right there. 0D 0A instead of just 0A.
>
> On Windows, 0D 0A is a correct line-end indicator. On Linux and on
> modern Macs, 0A is the right indicator. So your copy of Excel is
> preparing its CSV file for use on Windows, when it *should* be
> preparing it for use on the host system.

Well, should is a matter of opinion.  Here is at least one opinion about
what a CSV file is:

   1.  Each record is located on a separate line, delimited by a line
       break (CRLF).  For example:

       aaa,bbb,ccc CRLF
       zzz,yyy,xxx CRLF

This is from RFC 4180 (don't worry, it does explain that fields can span
lines later on).  In a court of law you could well argue that MS Excel
is doing the right thing here.  Whilst you may well say it should not do
this, it is certain that if it didn't, someone else will say that they
definitely should.

CSV files have no universally agreed separator (despite the name), no
universally agreed character encoding, no universally agreed line ending
and no universally agreed quoting scheme.  The only universally agreed
thing about them is that they are a pain in neck.

The sound advice about file formats: "be generous in what your code
accepts and strict in what it generates" is almost impossible to follow
here, but it would certainly require the file to be processed as a
binary stream.

Normally, for a beginner, all this unfortunate mess can be glossed over,
but if the files are being generated with CRLF endings it would appear
that it can't be avoided here.

<snip>
-- 
Ben.

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


#99644

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-16 12:41 +0000
Message-ID<o30nak$nd9$1@dont-email.me>
In reply to#99641
On 16/12/16 12:02, Ben Bacarisse wrote:
> Richard Heathfield <rjh@cpax.org.uk> writes:
<snip>
>> On Windows, 0D 0A is a correct line-end indicator. On Linux and on
>> modern Macs, 0A is the right indicator. So your copy of Excel is
>> preparing its CSV file for use on Windows, when it *should* be
>> preparing it for use on the host system.
>
> Well, should is a matter of opinion.  Here is at least one opinion about
> what a CSV file is:
>
>    1.  Each record is located on a separate line, delimited by a line
>        break (CRLF).  For example:
>
>        aaa,bbb,ccc CRLF
>        zzz,yyy,xxx CRLF
>
> This is from RFC 4180

I take your point, but let's look at the context:

    While there are various specifications and implementations for the
    CSV format (for ex. [4], [5], [6] and [7]), there is no formal
    specification in existence, which allows for a wide variety of
    interpretations of CSV files.  This section documents the format that
    seems to be followed by most implementations:

    1.  Each record is located on a separate line, delimited by a line
        break (CRLF).

So it is reporting what the author /believes/ to be the practice 
followed by /most/ implementations. And I doubt very much whether Y 
Shafranovich stopped to consider whether that was the practice followed 
on *nix-like systems. Furthermore, the disclaimer at the top of the 
document makes it clear that this is *not* even an Internet standard, 
let alone a general computing standard.

CRLF is often specified in RFCs, and it can surely only be a sop to 
Microsoft. I can think of no other reason for it, anyway. If MS would 
only do the decent thing and drop this ridiculous convention, a whole 
universe of pain could be avoided.

> (don't worry, it does explain that fields can span
> lines later on).  In a court of law you could well argue that MS Excel
> is doing the right thing here.  Whilst you may well say it should not do
> this, it is certain that if it didn't, someone else will say that they
> definitely should.
>
> CSV files have no universally agreed separator (despite the name), no
> universally agreed character encoding, no universally agreed line ending
> and no universally agreed quoting scheme.  The only universally agreed
> thing about them is that they are a pain in neck.

Well, that's certainly true. No doubt we all have our own preferences. 
Personally, if I have the choice, I choose tab separators, \n line 
endings, and straight ASCII encoding, high bit always clear. (Obviously 
that isn't going to suit everybody.)

> The sound advice about file formats: "be generous in what your code
> accepts and strict in what it generates" is almost impossible to follow
> here, but it would certainly require the file to be processed as a
> binary stream.
>
> Normally, for a beginner, all this unfortunate mess can be glossed over,
> but if the files are being generated with CRLF endings it would appear
> that it can't be avoided here.

Easy to fix, though - dos2unix will do it.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99649

FromBartC <bc@freeuk.com>
Date2016-12-16 13:40 +0000
Message-ID<o30qpa$3jg$1@dont-email.me>
In reply to#99644
On 16/12/2016 12:41, Richard Heathfield wrote:

> CRLF is often specified in RFCs, and it can surely only be a sop to
> Microsoft. I can think of no other reason for it, anyway.

I think CRLF was around long before Microsoft. Something to do with 
driving a teletype I understand.

> If MS would
> only do the decent thing and drop this ridiculous convention, a whole
> universe of pain could be avoided.

If the main line-endings are either CRLF or LF (and you disallow 
individual LF or CR within text that were once used for cursor control) 
then it isn't much problem to deal with either convention.

My programs do that and since then I've never had a problem with my 
editor for example dealing with either kind of file (unlike Notepad).

I find dealing properly with tabs is a bigger problem.

> Easy to fix, though - dos2unix will do it.

That's funny, I used to have a program called ADDCR to do the opposite. 
Which I no longer need.


-- 
Bartc

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


#99652

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-16 14:03 +0000
Message-ID<o30s58$88l$2@dont-email.me>
In reply to#99649
On 16/12/16 13:40, BartC wrote:
> On 16/12/2016 12:41, Richard Heathfield wrote:
>
>> CRLF is often specified in RFCs, and it can surely only be a sop to
>> Microsoft. I can think of no other reason for it, anyway.
>
> I think CRLF was around long before Microsoft. Something to do with
> driving a teletype I understand.

Yes, that's right. I didn't say they invented it. I said they should 
stop using it. Either that, or they should invest in a buggy whip factory.

>> If MS would
>> only do the decent thing and drop this ridiculous convention, a whole
>> universe of pain could be avoided.
>
> If the main line-endings are either CRLF or LF (and you disallow
> individual LF or CR within text that were once used for cursor control)
> then it isn't much problem to deal with either convention.

Of course not, if you know about it and know how to deal with it. It's 
still a nuisance, though.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99646

FromBartC <bc@freeuk.com>
Date2016-12-16 13:03 +0000
Message-ID<o30oks$rn1$1@dont-email.me>
In reply to#99641
On 16/12/2016 12:02, Ben Bacarisse wrote:

> Well, should is a matter of opinion.  Here is at least one opinion about
> what a CSV file is:
>
>    1.  Each record is located on a separate line, delimited by a line
>        break (CRLF).  For example:
>
>        aaa,bbb,ccc CRLF
>        zzz,yyy,xxx CRLF
>
> This is from RFC 4180 (don't worry, it does explain that fields can span
> lines later on).

Big mistake. Apparently leading and trailing spaces are also significant.

This means that a big chunk of a file spanning multiple lines containing 
English prose, or function of a programming language, counts as just one 
CSV field so long as there aren't any commas in there.

(And apparently a quoted field can still contain unadorned newline 
characters. So even fgets can only retrieve part of a field. Such 
characters should be escaped. Newline should be a higher level separator 
than comma.)

> CSV files have no universally agreed separator (despite the name), no
> universally agreed character encoding, no universally agreed line ending
> and no universally agreed quoting scheme.  The only universally agreed
> thing about them is that they are a pain in neck.

If your program generates CSV then you can do it properly so that you 
can read your own files and make it more likely for them to be 
acceptable to other programs. But you might still have the headache of 
dealing with embedded special characters within a field.

> The sound advice about file formats: "be generous in what your code
> accepts and strict in what it generates"

Oh, that's what I just repeated...

-- 
Bartc

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


#99655

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-16 15:04 +0000
Message-ID<874m233ogi.fsf@bsb.me.uk>
In reply to#99646
BartC <bc@freeuk.com> writes:

> On 16/12/2016 12:02, Ben Bacarisse wrote:
>
>> Well, should is a matter of opinion.  Here is at least one opinion about
>> what a CSV file is:
>>
>>    1.  Each record is located on a separate line, delimited by a line
>>        break (CRLF).  For example:
>>
>>        aaa,bbb,ccc CRLF
>>        zzz,yyy,xxx CRLF
>>
>> This is from RFC 4180 (don't worry, it does explain that fields can span
>> lines later on).
>
> Big mistake. Apparently leading and trailing spaces are also
> significant.

I'm not sure what the mistake is.  Can you explain?

> This means that a big chunk of a file spanning multiple lines
> containing English prose, or function of a programming language,
> counts as just one CSV field so long as there aren't any commas in
> there.

I know this is meant to explain the "big mistake" but I still don't see
it.

I don't think commas are really an issue since in every CSV format I've
seen fields with multiple lines have to be quoted.  But since there can
be two kind of "line" in a CSV file, it's possible that commas might
come into it, but I'm not sure that's what you mean.

For example, in a file with CRLF line endings, I can imagine a really
nasty CSV file with multi-line text whose line separator is LF:

  f1,f2,thisLFisLFfourLFlinesCRLF

(I don't know it any software either write this or reads it, but I can
imagine it being possible in some badly specified formats.)

> (And apparently a quoted field can still contain unadorned newline
> characters. So even fgets can only retrieve part of a field. Such
> characters should be escaped. Newline should be a higher level
> separator than comma.)

Yes.  You should not use fgets to read binary files.  You /can/, of
course, but I can't see the point other than give yourself a lot of
pain.

>> CSV files have no universally agreed separator (despite the name), no
>> universally agreed character encoding, no universally agreed line ending
>> and no universally agreed quoting scheme.  The only universally agreed
>> thing about them is that they are a pain in neck.
>
> If your program generates CSV then you can do it properly so that you
> can read your own files and make it more likely for them to be
> acceptable to other programs. But you might still have the headache of
> dealing with embedded special characters within a field.
>
>> The sound advice about file formats: "be generous in what your code
>> accepts and strict in what it generates"
>
> Oh, that's what I just repeated...

Yes, though I went on to say that it's almost impossible to do.  Your
"you can do it properly" makes it sound easy.

-- 
Ben.

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


#99658

FromBartC <bc@freeuk.com>
Date2016-12-16 15:26 +0000
Message-ID<o31112$paq$1@dont-email.me>
In reply to#99655
On 16/12/2016 15:04, Ben Bacarisse wrote:

>> Big mistake. Apparently leading and trailing spaces are also
>> significant.
>
> I'm not sure what the mistake is.  Can you explain?
>
>> This means that a big chunk of a file spanning multiple lines
>> containing English prose, or function of a programming language,
>> counts as just one CSV field so long as there aren't any commas in
>> there.
>
> I know this is meant to explain the "big mistake" but I still don't see
> it.

The mistake is having 'comma' be more important than 'newline'. Which 
can also make this ambiguous:

   abc,def
   ghi,jkl

Under strict CSV interpretation, that could be one record with three fields:

   abc,def\nghi,jkl

If you know the number of fields, that might help disambiguate. But CSV 
files usually don't state that.

> I don't think commas are really an issue since in every CSV format I've
> seen fields with multiple lines have to be quoted.

That doesn't really help. If the above example really was 3 fields, then 
quoting it would produce this:

   abc,"def
   ghi",jkl

There is still a 'hard' newline character in the middle of the field. 
Generic line-oriented text-handling, including fgets, will read that as 
two separate lines.

Fiddly CSV-aware code, or that handles this stuff as s low-level 
character-at-a-time stream, might be able to handle that. But you want 
to keep it simple. For example, a routine to copy a CSV file and tack an 
extra field on the end of each line would be trivial if it wasn't for 
that fact that some newlines could be embedded elements of some fields.

>> (And apparently a quoted field can still contain unadorned newline
>> characters. So even fgets can only retrieve part of a field. Such
>> characters should be escaped. Newline should be a higher level
>> separator than comma.)
>
> Yes.  You should not use fgets to read binary files.

CSV is a text format, not binary. That's the point of CSV. From what I 
can find out, there isn't an escape scheme for embedded control 
characters, as would be needed in string literals in source code for 
example.

>> If your program generates CSV then you can do it properly so that you
>> can read your own files and make it more likely for them to be
>> acceptable to other programs.

> Yes, though I went on to say that it's almost impossible to do.  Your
> "you can do it properly" makes it sound easy.

Easy to write and re-read your own files. Well, it's a little more 
fiddly if you allow that some character fields can contain non-printable 
characters (or separators or whitespace) as you need to invent or import 
a string escape scheme.

-- 
Bartc

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


#99664

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-16 17:01 +0000
Message-ID<87mvfv24fs.fsf@bsb.me.uk>
In reply to#99658
BartC <bc@freeuk.com> writes:

> On 16/12/2016 15:04, Ben Bacarisse wrote:
>
>>> Big mistake. Apparently leading and trailing spaces are also
>>> significant.
>>
>> I'm not sure what the mistake is.  Can you explain?
>>
>>> This means that a big chunk of a file spanning multiple lines
>>> containing English prose, or function of a programming language,
>>> counts as just one CSV field so long as there aren't any commas in
>>> there.
>>
>> I know this is meant to explain the "big mistake" but I still don't see
>> it.
>
> The mistake is having 'comma' be more important than 'newline'. Which
> can also make this ambiguous:
>
>   abc,def
>   ghi,jkl
>
> Under strict CSV interpretation, that could be one record with three fields:
>
>   abc,def\nghi,jkl

I don't know why you think that.  As far as I know, unquoted line ending
are record separators.

Of course, any CSV specification that had this ambiguity would indeed be
a big mistake but I don't know how you got there from what I quoted.

> If you know the number of fields, that might help disambiguate. But
> CSV files usually don't state that.
>
>> I don't think commas are really an issue since in every CSV format I've
>> seen fields with multiple lines have to be quoted.
>
> That doesn't really help. If the above example really was 3 fields,
> then quoting it would produce this:
>
>   abc,"def
>   ghi",jkl
>
> There is still a 'hard' newline character in the middle of the
> field. Generic line-oriented text-handling, including fgets, will read
> that as two separate lines.

If you read a CSV file with fgets you need to handle (or, I suppose,
ignore) the complications that leads to.  Bit since the most general
form of CSV file should be read as a binary stream (in the sense that
you can't assume your system's line ending will be used) reading it with
fgets is a really bad idea (though even that could be made to work).

> Fiddly CSV-aware code, or that handles this stuff as s low-level
> character-at-a-time stream, might be able to handle that. But you want
> to keep it simple. For example, a routine to copy a CSV file and tack
> an extra field on the end of each line would be trivial if it wasn't
> for that fact that some newlines could be embedded elements of some
> fields.

If you know the line ending and the quoting method used, that's not
really hard (maybe the other side of trival, but not hard).  If you
don't know the quoting method or the line ending, it's impossible.  CSV
is a mess.

>>> (And apparently a quoted field can still contain unadorned newline
>>> characters. So even fgets can only retrieve part of a field. Such
>>> characters should be escaped. Newline should be a higher level
>>> separator than comma.)
>>
>> Yes.  You should not use fgets to read binary files.
>
> CSV is a text format, not binary.

I'm using C's terminology here.  It's a binary file in that you don't
want to apply your host system's line-end translation to the IO.  You
/can/ treat a CSV file as a text file, but I've found that to be a bad
idea in general.

> That's the point of CSV. From what I
> can find out, there isn't an escape scheme for embedded control
> characters, as would be needed in string literals in source code for
> example.

Yes, in everyday tech. language it's a text format, but you should read
CSV files (for best results) as binary streams in C.

>>> If your program generates CSV then you can do it properly so that you
>>> can read your own files and make it more likely for them to be
>>> acceptable to other programs.
>
>> Yes, though I went on to say that it's almost impossible to do.  Your
>> "you can do it properly" makes it sound easy.
>
> Easy to write and re-read your own files.

Yes, that's certainly easy.

> Well, it's a little more
> fiddly if you allow that some character fields can contain
> non-printable characters (or separators or whitespace) as you need to
> invent or import a string escape scheme.

And it's way more than fiddly if you need to be able to read, correctly,
every CSV file out there as well write CSV files that can be read by
every CSV reader out there.  That's the "almost impossible" I was
referring to.

-- 
Ben.

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


#99643

FromAlla _ <modelling.data@gmail.com>
Date2016-12-16 04:18 -0800
Message-ID<8ac2c0e7-56ee-4c80-b2c5-2e7d3a959b10@googlegroups.com>
In reply to#99637
On Friday, December 16, 2016 at 2:29:02 PM UTC+3, Richard Heathfield wrote:
> On 16/12/16 11:06, Alla _ wrote:
> > On Friday, December 16, 2016 at 1:11:58 PM UTC+3, Richard Heathfield wrote:
> >> On 16/12/16 09:25, Alla _ wrote:
> >>> On Thursday, December 15, 2016 at 10:31:28 PM UTC+3, Richard Heathfield wrote:
> >>>> On 15/12/16 17:25, Alla _ wrote:
> > <snip>
> >> Hex dump, please.
> >>
> > Below I post:
> > (1) The corrected version of the program based on comments I have received;
> 
> I will make only one comment on the program, because I think first we 
> need to sort out your data.
> 
> > (2) csv inputs
> > (3) program's outputs
> > (4) hex dumps for each csv
> > Interesting: now that I have changed the error checking method, i.e. if (!ferror(fp)),
> > instead of checking for !feof, I get the error message at the end of the whole output;
> > this is telling me that there is something wrong with every csv file.
> 
> Yeah, your logic says:
> 
> IF there is NOT an error
>    Report an error
oops! ))) I have no idea how that ! has appeared there )
> 
<snip>

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


#99496

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-15 14:12 +0000
Message-ID<o2u8a9$3n0$1@dont-email.me>
In reply to#99491
[the code]

On 15/12/16 13:05, Alla _ wrote:

> (3) I will use a header file, in which I will store preprocessor commands, like
> #define and #include, as well as functions' declarations, etc.;

A well-designed header contains *only* the following:

1) inclusion guards;
2) macro definitions (#defines);
3) type definitions (typedefs);
4) function prototypes;
5) comments;
6) #include directives *ONLY* for those headers that are required for 
the immediate purposes of the header itself.

For example, here's a quick header I threw together a year or so ago:

/* CISPRNG - Cryptographically In-Secure
  * Pseudo-Random Number Generator
  *
  * Written by Richard Heathfield,
  * 20 October 2015.
  *
  * You will also need cisprng.c and a
  * C compiler.
  *
  * The author places this code into the
  * public domain, and so it may be freely
  * used for any legal purpose, although
  * I would recommend against using it
  * in circumstances where you really need
  * a cryptographically secure PRNG, because
  * it isn't one.
  */
#ifndef H_CISPRNG_H_
#define H_CISPRNG_H_

#define CISPRNG_RAND_MAX (0x7FFFFFFFUL)

/* Single state versions */
/* set the seed */
void cisprng_set(unsigned long seed);
/* get a PRN */
unsigned long cisprng_random(void);
/* get a PRN in a range */
unsigned long cisprng_range(unsigned long low,
                             unsigned long high);
/* Custom state versions */
unsigned long cisprng_csrandom(unsigned long *pseed);
unsigned long cisprng_csrange(unsigned long *pseed,
                               unsigned long low,
                               unsigned long high);
#endif
/* end of cisprng.h */

Note that it doesn't define any types. But if it did, they would go 
after the #defines but before the function prototypes. Nor does it 
include any headers. But *if* I'd used, say, size_t *in the header*, I'd 
have included <stddef.h> in the header. But I would *not* include 
<stddef.h> in the header just because the corresponding C file used 
size_t (which, actually, it doesn't). A module header is not a place to 
hide #includes.

> #include <stdio.h>
> #include <stdlib.h>
> #include <ctype.h>
> #include <string.h>
>
>
> #define BUFFER_SIZE 100
> //#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
> #define INCOME_STATEMENT "files/income_test.csv"
>
> int main(int argc, char *argv[])
> {
>     //check for correct number of arguments
>     if(argc > 2)
>     {
>         printf("Usage: program_name [file_name]");

You might want a \n on there. Or use puts() instead if you prefer.

Otherwise, this happens:

Usage: program_name [file_name]me@mymachine$

which probably isn't what you wanted to see.

>         return EXIT_FAILURE;
>     }
>     //determine a file to use
>     char *data_file = (argc == 2)? argv[1] : INCOME_STATEMENT;

I don't suppose you plan to change the filename, so why not make this const?

const char *data_file = (argc == 2)? argv[1] : INCOME_STATEMENT;

This will remove the *only* diagnostic message that gcc gave me (and by 
the way, to get only one warning when using my flag choices is quite an 
achievement!).

What should the program do if there are several arguments? At the 
moment, if I tell it:

./alla test1.csv test2.csv

I get this message:

Usage: program_name [file_name]

If the program can only handle one data file, I would expect to see 
something like:

Sorry, I can only process one file. Ignoring subsequent arguments...

which you would code like this:

const char *data_file = (argc > 1)? argv[1] : INCOME_STATEMENT;
if(argc > 2)
{
   fputs("Sorry, I can only process one file."
         " Ignoring subsequent arguments...\n",
         stderr);
}

>
>     FILE *fp = fopen(data_file, "r");
>
>     if ( fp )
>     {
>         char buffer[BUFFER_SIZE] = "";
>         char array_names[50][50];
>         int  array_values[50][50];

I am taking you at your word and forbearing to comment on these values, 
but for the sake of a predictable life I would suggest that you 
initialise these two arrays:

char array_names[50][50] = {0};
int  array_values[50][50] = {0};

which will take advantage of the default static initialisation rule to 
set everything to 0.

>         char *ptr_buffer = NULL;
>         size_t i, j, k;
>
>         //Read each line from the file, store in the buffer
>         for ( i = 0; fgets(buffer, sizeof(buffer), fp) != NULL; ++i )

Since i isn't part of the loop control logic, I would suggest that you 
replace this line with the much more usual:

   i = 0;
   while(fgets(buffer, sizeof buffer, fp) != NULL)
   {
     /* stuff */
     i++;
   }

And if i is a line number, why not call it line_number? That's much more 
descriptive than i.

The loop body looked more or less okay to me, except that it's a touch 
on the large side. Think about functional decomposition.

>         if (!feof(fp))
>         {
>             puts("Something went wrong with the provided file\n");
>             return EXIT_FAILURE;
>         }

Why not use ferror(fp) instead? It's a more direct description of what 
you're trying to find out:

   if(ferror(fp))
   {

And while we're on the subject, diagnostic messages sit much better on 
stderr than on stdout. That way, they can be separated from the 
program's normal output, like this:

./alla test1.csv > test1.out 2> test1.log

which will put stdout stuff into test1.out and stderr stuff into test1.log.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99503

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-15 16:14 +0100
Message-ID<o2ubtq$hb6$1@dont-email.me>
In reply to#99496
On 15/12/16 15:12, Richard Heathfield wrote:
> [the code]
> 
> On 15/12/16 13:05, Alla _ wrote:
> 
>> (3) I will use a header file, in which I will store preprocessor
>> commands, like
>> #define and #include, as well as functions' declarations, etc.;
> 
> A well-designed header contains *only* the following:
> 
> 1) inclusion guards;
> 2) macro definitions (#defines);
> 3) type definitions (typedefs);
> 4) function prototypes;
> 5) comments;
> 6) #include directives *ONLY* for those headers that are required for
> the immediate purposes of the header itself.
> 
> For example, here's a quick header I threw together a year or so ago:
> 
> /* CISPRNG - Cryptographically In-Secure
>  * Pseudo-Random Number Generator
>  *
>  * Written by Richard Heathfield,
>  * 20 October 2015.
>  *
>  * You will also need cisprng.c and a
>  * C compiler.
>  *
>  * The author places this code into the
>  * public domain, and so it may be freely
>  * used for any legal purpose, although
>  * I would recommend against using it
>  * in circumstances where you really need
>  * a cryptographically secure PRNG, because
>  * it isn't one.
>  */
> #ifndef H_CISPRNG_H_
> #define H_CISPRNG_H_
> 
> #define CISPRNG_RAND_MAX (0x7FFFFFFFUL)
> 
> /* Single state versions */
> /* set the seed */
> void cisprng_set(unsigned long seed);
> /* get a PRN */
> unsigned long cisprng_random(void);
> /* get a PRN in a range */
> unsigned long cisprng_range(unsigned long low,
>                             unsigned long high);
> /* Custom state versions */
> unsigned long cisprng_csrandom(unsigned long *pseed);
> unsigned long cisprng_csrange(unsigned long *pseed,
>                               unsigned long low,
>                               unsigned long high);
> #endif
> /* end of cisprng.h */
> 
> Note that it doesn't define any types. But if it did, they would go
> after the #defines but before the function prototypes. Nor does it
> include any headers. But *if* I'd used, say, size_t *in the header*, I'd
> have included <stddef.h> in the header. But I would *not* include
> <stddef.h> in the header just because the corresponding C file used
> size_t (which, actually, it doesn't). A module header is not a place to
> hide #includes.
> 

I hope I am not going to cause too much confusion to a learner here, but
I have a few comments about your rules for headers.  It may be that you
agree with me, and just did not write your complete rule set.

I think it is important to emphasis that you should only have macros,
types, function prototypes, etc., in a header if these declarations will
be used by other modules.  Anything that is used only within the
implementation C file, should be in that file alone - and not the
header.  So if you have a function "cisprng_calculate" that is not
exported, it should not be declared in the header file, and it should be
declared "static" in the C file.

Regarding macros, I would always limit the use of macros to when you
actually need them to be macros.  If usage of CISPRNG_RAND_MAX permits,
I would prefer:

static const unsigned long int cisprng_rand_max = 0x7ffffffful;

The rules of "const" objects in C mean that you often /do/ need to make
such things #define'd values rather than static consts.

Assuming you are using C99 or C11 rather than C90 (I know some people
still use C90), then "static inline" functions are often a better
alternative to function-like macros, and can go in headers as well.


I would also put more emphasis on the comments.  Ideally, the comments
in a header should tell the reader all they need to know about the
functions and how to use them.  It makes it easier for people using the
code - they don't have to look elsewhere for documentation.  Of course,
there are limits - comments should not be so extensive that it is hard
to see the code!

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


#99508

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-15 15:37 +0000
Message-ID<o2uda0$mjd$1@dont-email.me>
In reply to#99503
On 15/12/16 15:14, David Brown wrote:
> On 15/12/16 15:12, Richard Heathfield wrote:
>> [the code]
>>
>> On 15/12/16 13:05, Alla _ wrote:
>>
>>> (3) I will use a header file, in which I will store preprocessor
>>> commands, like
>>> #define and #include, as well as functions' declarations, etc.;
>>
>> A well-designed header contains *only* the following:
>>
>> 1) inclusion guards;
>> 2) macro definitions (#defines);
>> 3) type definitions (typedefs);
>> 4) function prototypes;
>> 5) comments;
>> 6) #include directives *ONLY* for those headers that are required for
>> the immediate purposes of the header itself.
>>
>> For example, here's a quick header I threw together a year or so ago:
>>
>> /* CISPRNG - Cryptographically In-Secure
>>  * Pseudo-Random Number Generator
>>  *
>>  * Written by Richard Heathfield,
>>  * 20 October 2015.
>>  *
>>  * You will also need cisprng.c and a
>>  * C compiler.
>>  *
>>  * The author places this code into the
>>  * public domain, and so it may be freely
>>  * used for any legal purpose, although
>>  * I would recommend against using it
>>  * in circumstances where you really need
>>  * a cryptographically secure PRNG, because
>>  * it isn't one.
>>  */
>> #ifndef H_CISPRNG_H_
>> #define H_CISPRNG_H_
>>
>> #define CISPRNG_RAND_MAX (0x7FFFFFFFUL)
>>
>> /* Single state versions */
>> /* set the seed */
>> void cisprng_set(unsigned long seed);
>> /* get a PRN */
>> unsigned long cisprng_random(void);
>> /* get a PRN in a range */
>> unsigned long cisprng_range(unsigned long low,
>>                             unsigned long high);
>> /* Custom state versions */
>> unsigned long cisprng_csrandom(unsigned long *pseed);
>> unsigned long cisprng_csrange(unsigned long *pseed,
>>                               unsigned long low,
>>                               unsigned long high);
>> #endif
>> /* end of cisprng.h */
>>
>> Note that it doesn't define any types. But if it did, they would go
>> after the #defines but before the function prototypes. Nor does it
>> include any headers. But *if* I'd used, say, size_t *in the header*, I'd
>> have included <stddef.h> in the header. But I would *not* include
>> <stddef.h> in the header just because the corresponding C file used
>> size_t (which, actually, it doesn't). A module header is not a place to
>> hide #includes.
>>
>
> I hope I am not going to cause too much confusion to a learner here, but
> I have a few comments about your rules for headers.  It may be that you
> agree with me, and just did not write your complete rule set.

I think we might be able to save Alla some confusion here by suggesting 
that she avert her eyes. :-)

> I think it is important to emphasis that you should only have macros,
> types, function prototypes, etc., in a header if these declarations will
> be used by other modules.

Yes, but.

With me so far? :-)

I was going to dig out a quotation from King Lear about not taking 
things far enough, but it turned out not to be quite so apt as I'd 
hoped. Oh well.

Module, right? Well, we have to say what we mean by "module". We might 
reasonably define it as a source and its associated header, in which 
case I think your point is fine. But we might also define it as a set of 
related functions, which might be spread over several sources. If we 
define it that way (and, frankly, I do), then it becomes reasonable to 
think of a module as having two headers: one public, and one private. 
The private header is shared across all the sources that go to make up 
that module, and the public header is shared across other modules.

So, for example, we might have an abstract data type that is defined in 
mylittlemoduleinternal.h and shared across mylittlemoduleA.c, 
mylittlemoduleB.c, and mylittlemoduleC.c. And then we have a bunch of 
prototypes listed in mylittlemodule.h, for sharing with other modules.

Would you agree with that?

> Anything that is used only within the
> implementation C file, should be in that file alone - and not the
> header.  So if you have a function "cisprng_calculate" that is not
> exported, it should not be declared in the header file, and it should be
> declared "static" in the C file.

But if it is needed by other sources within the same module, that gives 
us a problem. One possible solution is to share a function pointer in 
the private header --- but it's messy.

> Regarding macros, I would always limit the use of macros to when you
> actually need them to be macros.  If usage of CISPRNG_RAND_MAX permits,
> I would prefer:
>
> static const unsigned long int cisprng_rand_max = 0x7ffffffful;

Yeah, but this is C90, and it's an array size. :-)

Okay, obviously it isn't. But I'm sure you take my point. That one could 
indeed have been a const, but that isn't always possible.

> The rules of "const" objects in C mean that you often /do/ need to make
> such things #define'd values rather than static consts.

Yes.

> Assuming you are using C99 or C11 rather than C90 (I know some people
> still use C90),

You hear that, folks? David thinks I'm *some people*! Fame at last!

> then "static inline" functions are often a better
> alternative to function-like macros, and can go in headers as well.
>
> I would also put more emphasis on the comments.  Ideally, the comments
> in a header should tell the reader all they need to know about the
> functions and how to use them.

Up to a point, Lord Copper.

> It makes it easier for people using the
> code - they don't have to look elsewhere for documentation.  Of course,
> there are limits - comments should not be so extensive that it is hard
> to see the code!

And that's why we have external docs.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99577

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-15 23:20 +0100
Message-ID<o2v4s3$hpv$1@dont-email.me>
In reply to#99508
On 15/12/16 16:37, Richard Heathfield wrote:
> On 15/12/16 15:14, David Brown wrote:
>> On 15/12/16 15:12, Richard Heathfield wrote:
>>> [the code]
>>>
>>> On 15/12/16 13:05, Alla _ wrote:
>>>
>>>> (3) I will use a header file, in which I will store preprocessor
>>>> commands, like
>>>> #define and #include, as well as functions' declarations, etc.;
>>>
>>> A well-designed header contains *only* the following:
>>>
>>> 1) inclusion guards;
>>> 2) macro definitions (#defines);
>>> 3) type definitions (typedefs);
>>> 4) function prototypes;
>>> 5) comments;
>>> 6) #include directives *ONLY* for those headers that are required for
>>> the immediate purposes of the header itself.
>>>
>>> For example, here's a quick header I threw together a year or so ago:
>>>
>>> /* CISPRNG - Cryptographically In-Secure
>>>  * Pseudo-Random Number Generator
>>>  *
>>>  * Written by Richard Heathfield,
>>>  * 20 October 2015.
>>>  *
>>>  * You will also need cisprng.c and a
>>>  * C compiler.
>>>  *
>>>  * The author places this code into the
>>>  * public domain, and so it may be freely
>>>  * used for any legal purpose, although
>>>  * I would recommend against using it
>>>  * in circumstances where you really need
>>>  * a cryptographically secure PRNG, because
>>>  * it isn't one.
>>>  */
>>> #ifndef H_CISPRNG_H_
>>> #define H_CISPRNG_H_
>>>
>>> #define CISPRNG_RAND_MAX (0x7FFFFFFFUL)
>>>
>>> /* Single state versions */
>>> /* set the seed */
>>> void cisprng_set(unsigned long seed);
>>> /* get a PRN */
>>> unsigned long cisprng_random(void);
>>> /* get a PRN in a range */
>>> unsigned long cisprng_range(unsigned long low,
>>>                             unsigned long high);
>>> /* Custom state versions */
>>> unsigned long cisprng_csrandom(unsigned long *pseed);
>>> unsigned long cisprng_csrange(unsigned long *pseed,
>>>                               unsigned long low,
>>>                               unsigned long high);
>>> #endif
>>> /* end of cisprng.h */
>>>
>>> Note that it doesn't define any types. But if it did, they would go
>>> after the #defines but before the function prototypes. Nor does it
>>> include any headers. But *if* I'd used, say, size_t *in the header*, I'd
>>> have included <stddef.h> in the header. But I would *not* include
>>> <stddef.h> in the header just because the corresponding C file used
>>> size_t (which, actually, it doesn't). A module header is not a place to
>>> hide #includes.
>>>
>>
>> I hope I am not going to cause too much confusion to a learner here, but
>> I have a few comments about your rules for headers.  It may be that you
>> agree with me, and just did not write your complete rule set.
>
> I think we might be able to save Alla some confusion here by suggesting
> that she avert her eyes. :-)
>
>> I think it is important to emphasis that you should only have macros,
>> types, function prototypes, etc., in a header if these declarations will
>> be used by other modules.
>
> Yes, but.
>
> With me so far? :-)

Yes...

>
> I was going to dig out a quotation from King Lear about not taking
> things far enough, but it turned out not to be quite so apt as I'd
> hoped. Oh well.
>
> Module, right? Well, we have to say what we mean by "module". We might
> reasonably define it as a source and its associated header, in which
> case I think your point is fine.

Yes, that is what I was meaning by "module".  Of course you are correct 
that I should have defined it - especially as it could mean other things.

> But we might also define it as a set of
> related functions, which might be spread over several sources. If we
> define it that way (and, frankly, I do), then it becomes reasonable to
> think of a module as having two headers: one public, and one private.
> The private header is shared across all the sources that go to make up
> that module, and the public header is shared across other modules.

Agreed.

If you prefer to call this sort of multi-file "lump" a "module", what do 
you call a header/C file "lump" ?

It is a real shame that C has no good way of dealing with this sort of 
thing properly - no namespaces, and only two levels of identifier 
visibility (static to a compilation unit, or global for the whole program).

>
> So, for example, we might have an abstract data type that is defined in
> mylittlemoduleinternal.h and shared across mylittlemoduleA.c,
> mylittlemoduleB.c, and mylittlemoduleC.c. And then we have a bunch of
> prototypes listed in mylittlemodule.h, for sharing with other modules.
>
> Would you agree with that?

Yes, that seems reasonable.  It is not exactly how I would organise it, 
but close enough for now.

>
>> Anything that is used only within the
>> implementation C file, should be in that file alone - and not the
>> header.  So if you have a function "cisprng_calculate" that is not
>> exported, it should not be declared in the header file, and it should be
>> declared "static" in the C file.
>
> But if it is needed by other sources within the same module, that gives
> us a problem. One possible solution is to share a function pointer in
> the private header --- but it's messy.

Yes.

In this particular case, the program is small enough that such 
multi-file modules are not going to be necessary, so a simpler system is 
possible.  But the simpler system does not scale to a more hierarchical 
organisation without changes such as you suggest.

>
>> Regarding macros, I would always limit the use of macros to when you
>> actually need them to be macros.  If usage of CISPRNG_RAND_MAX permits,
>> I would prefer:
>>
>> static const unsigned long int cisprng_rand_max = 0x7ffffffful;
>
> Yeah, but this is C90, and it's an array size. :-)
>
> Okay, obviously it isn't. But I'm sure you take my point. That one could
> indeed have been a const, but that isn't always possible.
>

As I note below.

In some circumstances you can use a enum constant instead of a #define'd 
constant when a "static const" won't work - but I find that to be rather 
artificial unless it is part of a collection of constants for which an 
enum makes sense.

>> The rules of "const" objects in C mean that you often /do/ need to make
>> such things #define'd values rather than static consts.
>
> Yes.
>
>> Assuming you are using C99 or C11 rather than C90 (I know some people
>> still use C90),
>
> You hear that, folks? David thinks I'm *some people*! Fame at last!

I am sure you have good reasons for using C90.  But I think it usually 
makes sense for someone relatively new to C to use C99 features when 
they make coding clearer (following Heathfield's rule, naturally) - C99 
is the current dominant C standard used, I believe.  (And C11 doesn't 
add much that I find useful - at least not beyond the gcc extensions I 
have used for years.  Static assertions are great, but you could do them 
with an ugly macro in C90 and C99.)

>
>> then "static inline" functions are often a better
>> alternative to function-like macros, and can go in headers as well.
>>
>> I would also put more emphasis on the comments.  Ideally, the comments
>> in a header should tell the reader all they need to know about the
>> functions and how to use them.
>
> Up to a point, Lord Copper.
>
>> It makes it easier for people using the
>> code - they don't have to look elsewhere for documentation.  Of course,
>> there are limits - comments should not be so extensive that it is hard
>> to see the code!
>
> And that's why we have external docs.
>

If the usage documentation can be written in the header (without passing 
"the point"), then that is a good thing.  External documentation can go 
into more detail, examples, etc., but there is always the risk of 
getting out of synchronisation between the code and the document or 
simply not having the document at hand when you are working with the 
code.  Documentation in the header file is /always/ quickly at hand when 
you are working with the code!

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


#99582

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-15 23:27 +0000
Message-ID<o2v8qp$1vo$1@dont-email.me>
In reply to#99577
On 15/12/16 22:20, David Brown wrote:
> On 15/12/16 16:37, Richard Heathfield wrote:

<snip>

>> Module, right? Well, we have to say what we mean by "module". We might
>> reasonably define it as a source and its associated header, in which
>> case I think your point is fine.
>
> Yes, that is what I was meaning by "module".  Of course you are correct
> that I should have defined it - especially as it could mean other things.
>
>> But we might also define it as a set of
>> related functions, which might be spread over several sources. If we
>> define it that way (and, frankly, I do), then it becomes reasonable to
>> think of a module as having two headers: one public, and one private.
>> The private header is shared across all the sources that go to make up
>> that module, and the public header is shared across other modules.
>
> Agreed.
>
> If you prefer to call this sort of multi-file "lump" a "module", what do
> you call a header/C file "lump" ?

A lump. What else?

The correct term is "preprocessing translation unit". PTU, anyone? But I 
tend to eschew the P and stick to "translation unit" (which is actually 
the correct term for what remains after preprocessing, but I'm not too 
fussed about the difference except when arguing about the difference!).

> It is a real shame that C has no good way of dealing with this sort of
> thing properly - no namespaces, and only two levels of identifier
> visibility (static to a compilation unit, or global for the whole program).

Yes. I'd like to see an hierarchy of visibility. But it isn't going to 
happen, and I can live with that.

>> So, for example, we might have an abstract data type that is defined in
>> mylittlemoduleinternal.h and shared across mylittlemoduleA.c,
>> mylittlemoduleB.c, and mylittlemoduleC.c. And then we have a bunch of
>> prototypes listed in mylittlemodule.h, for sharing with other modules.
>>
>> Would you agree with that?
>
> Yes, that seems reasonable.  It is not exactly how I would organise it,
> but close enough for now.

I think that's important, actually. What I mean is, okay, you and I 
would tend to choose to organise stuff in different ways, but those 
differences are likely to be fairly minor, and each of us would 
recognise that the other has made reasonable choices that just happen to 
be different to our own reasonable choice. This is what cultural 
diversity is all about!

>>> Anything that is used only within the
>>> implementation C file, should be in that file alone - and not the
>>> header.  So if you have a function "cisprng_calculate" that is not
>>> exported, it should not be declared in the header file, and it should be
>>> declared "static" in the C file.
>>
>> But if it is needed by other sources within the same module, that gives
>> us a problem. One possible solution is to share a function pointer in
>> the private header --- but it's messy.
>
> Yes.

Yeeesss. It's... it isn't just messy, is it? It's actually icky. There 
is no /good/ solution, as far as I know.

What I actually do in this situation (when I get to choose, anyway) is 
to declare the function in the private header, and make it extern (not 
explicitly, but by not making it static), and then just not telling the 
user-programmer it's there! That way, even though they can in theory 
call it, first they have to find out about it, and they can only do that 
by going to some serious and deliberate investigative effort.

> In this particular case, the program is small enough that such
> multi-file modules are not going to be necessary, so a simpler system is
> possible.  But the simpler system does not scale to a more hierarchical
> organisation without changes such as you suggest.

Namespaces would be pleasant, wouldn't they? But we're not going to get 
them, and that's that.

>>> Assuming you are using C99 or C11 rather than C90 (I know some people
>>> still use C90),
>>
>> You hear that, folks? David thinks I'm *some people*! Fame at last!
>
> I am sure you have good reasons for using C90.  But I think it usually
> makes sense for someone relatively new to C to use C99 features when
> they make coding clearer (following Heathfield's rule, naturally)

My blushes, Watson!

My reasons for using C90 are as follows:

1) it works everywhere;
2) C99 doesn't add anything I need that I can't get from C++. So, if I 
need those features, I'll just write that code in C++ instead, which 
means I get lots of toys to play with.

> If the usage documentation can be written in the header (without passing
> "the point"), then that is a good thing.

A brief summary, yes.

> External documentation can go
> into more detail, examples, etc., but there is always the risk of
> getting out of synchronisation between the code and the document

But that's true of the internal documentation as well --- it can and 
does get out of synch with the code. The solution to synchronisation 
problems is discipline, and that's required whether the documentation is 
internal or external.

> or
> simply not having the document at hand when you are working with the
> code.  Documentation in the header file is /always/ quickly at hand when
> you are working with the code!

As long as you know the code well enough to know where to look, or know 
what you're looking for well enough to execute a grep. External docs can 
cover several headers in one indexed document. They can offer hyperlinks 
to specific function descriptions, they can contain diagrams (and I 
don't mean ASCII art), and they can use all the tricks of the word 
processing trade to make the document more readable than can generally 
be managed in eighty columns of Courier 12.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99632

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-16 12:10 +0100
Message-ID<o30i0a$58m$1@dont-email.me>
In reply to#99582
On 16/12/16 00:27, Richard Heathfield wrote:
> On 15/12/16 22:20, David Brown wrote:
>> On 15/12/16 16:37, Richard Heathfield wrote:
> 
> <snip>
> 
>>> Module, right? Well, we have to say what we mean by "module". We might
>>> reasonably define it as a source and its associated header, in which
>>> case I think your point is fine.
>>
>> Yes, that is what I was meaning by "module".  Of course you are correct
>> that I should have defined it - especially as it could mean other things.
>>
>>> But we might also define it as a set of
>>> related functions, which might be spread over several sources. If we
>>> define it that way (and, frankly, I do), then it becomes reasonable to
>>> think of a module as having two headers: one public, and one private.
>>> The private header is shared across all the sources that go to make up
>>> that module, and the public header is shared across other modules.
>>
>> Agreed.
>>
>> If you prefer to call this sort of multi-file "lump" a "module", what do
>> you call a header/C file "lump" ?
> 
> A lump. What else?
> 
> The correct term is "preprocessing translation unit". PTU, anyone? But I
> tend to eschew the P and stick to "translation unit" (which is actually
> the correct term for what remains after preprocessing, but I'm not too
> fussed about the difference except when arguing about the difference!).

No, a translation unit (or compilation unit) is something different.

If you have:

widget.h	// Declarations for widget functions
widget.c	// Implementation of widget functions
game.c		// Uses widget functions

Then widget.c + any files it #include's (hopefully including widget.h)
is a translation unit.  So is game.c + any files /it/ includes
(including widget.h).

I am wondering what you call the lump "widget.h + widget.c", if
anything?  Maybe it is just a "module" that happens to contain only two
files.

> 
>> It is a real shame that C has no good way of dealing with this sort of
>> thing properly - no namespaces, and only two levels of identifier
>> visibility (static to a compilation unit, or global for the whole
>> program).
> 
> Yes. I'd like to see an hierarchy of visibility. But it isn't going to
> happen, and I can live with that.

If you couldn't live with it, you wouldn't be here - you'd be next door
in c.l.c++ :-)

> 
>>> So, for example, we might have an abstract data type that is defined in
>>> mylittlemoduleinternal.h and shared across mylittlemoduleA.c,
>>> mylittlemoduleB.c, and mylittlemoduleC.c. And then we have a bunch of
>>> prototypes listed in mylittlemodule.h, for sharing with other modules.
>>>
>>> Would you agree with that?
>>
>> Yes, that seems reasonable.  It is not exactly how I would organise it,
>> but close enough for now.
> 
> I think that's important, actually. What I mean is, okay, you and I
> would tend to choose to organise stuff in different ways, but those
> differences are likely to be fairly minor, and each of us would
> recognise that the other has made reasonable choices that just happen to
> be different to our own reasonable choice. This is what cultural
> diversity is all about!

Yes.  Since C does not have support for "modules", "units",
"namespaces", "lumps", etc., beyond the humble #include mechanism, we
have the freedom to implement whatever balance of predictable rules and
flexibility suits the job at hand.

> 
>>>> Anything that is used only within the
>>>> implementation C file, should be in that file alone - and not the
>>>> header.  So if you have a function "cisprng_calculate" that is not
>>>> exported, it should not be declared in the header file, and it
>>>> should be
>>>> declared "static" in the C file.
>>>
>>> But if it is needed by other sources within the same module, that gives
>>> us a problem. One possible solution is to share a function pointer in
>>> the private header --- but it's messy.
>>
>> Yes.
> 
> Yeeesss. It's... it isn't just messy, is it? It's actually icky. There
> is no /good/ solution, as far as I know.
> 
> What I actually do in this situation (when I get to choose, anyway) is
> to declare the function in the private header, and make it extern (not
> explicitly, but by not making it static), and then just not telling the
> user-programmer it's there! That way, even though they can in theory
> call it, first they have to find out about it, and they can only do that
> by going to some serious and deliberate investigative effort.

That would work.

I use "extern" explicitly on function declarations in headers (except
for "static inline" functions, of course).  I know it is unnecessary,
but I feel that it should have been necessary - "extern by default" is a
design mistake in C, IMHO.  It also makes it more consistent with extern
variable declarations.  (In small embedded systems, it is often useful
to have "global variables".  The balance of tradeoffs is different than
on bigger systems.)

> 
>> In this particular case, the program is small enough that such
>> multi-file modules are not going to be necessary, so a simpler system is
>> possible.  But the simpler system does not scale to a more hierarchical
>> organisation without changes such as you suggest.
> 
> Namespaces would be pleasant, wouldn't they? But we're not going to get
> them, and that's that.

Indeed.

> 
>>>> Assuming you are using C99 or C11 rather than C90 (I know some people
>>>> still use C90),
>>>
>>> You hear that, folks? David thinks I'm *some people*! Fame at last!
>>
>> I am sure you have good reasons for using C90.  But I think it usually
>> makes sense for someone relatively new to C to use C99 features when
>> they make coding clearer (following Heathfield's rule, naturally)
> 
> My blushes, Watson!
> 
> My reasons for using C90 are as follows:
> 
> 1) it works everywhere;
> 2) C99 doesn't add anything I need that I can't get from C++. So, if I
> need those features, I'll just write that code in C++ instead, which
> means I get lots of toys to play with.

My reasons for using C99 are:

1) It works everywhere I need it to work.
2) It adds a lot of useful things to C without needing to go for C++.

I am seeing more interest in C++ in the sorts of systems I work with -
the combination of better compilers, useful features in C++11/C++14, and
more powerful microcontrollers at the small end mean that C++ is
feasible on projects where previously C was the only option.

But since I can use C99, I don't have quite the same pressure to move to
C++ as C90 programmers do :-)

> 
>> If the usage documentation can be written in the header (without passing
>> "the point"), then that is a good thing.
> 
> A brief summary, yes.
> 
>> External documentation can go
>> into more detail, examples, etc., but there is always the risk of
>> getting out of synchronisation between the code and the document
> 
> But that's true of the internal documentation as well --- it can and
> does get out of synch with the code. The solution to synchronisation
> problems is discipline, and that's required whether the documentation is
> internal or external.

Also true.  It is easier, however, to keep your internal documentation
in sync - you've got the file open and have made changes to the code in
it, so you can change the lines of text there too.  Your external
documentation might mean different tools, different procedures, etc. -
and it takes more discipline to get right.

The best is to write self-documenting code - then it is never out of
sync.  At least, don't write anything in comments that could be
expressed in code (such as by good choice of function and parameter names).

> 
>> or
>> simply not having the document at hand when you are working with the
>> code.  Documentation in the header file is /always/ quickly at hand when
>> you are working with the code!
> 
> As long as you know the code well enough to know where to look, or know
> what you're looking for well enough to execute a grep. External docs can
> cover several headers in one indexed document. They can offer hyperlinks
> to specific function descriptions, they can contain diagrams (and I
> don't mean ASCII art), and they can use all the tricks of the word
> processing trade to make the document more readable than can generally
> be managed in eighty columns of Courier 12.
> 

Some of use have moved to using more capable IDE's for their development
work...

Of course you are correct that external documentation can have more
features and flexibility than internal documentation in comments.

It is also possible to make combinations of the two.  On one customer
project I made extensive use of doxygen.  So each item in the headers
had doxygen comments, and there were comment blocks giving a bit more
general information about the modules (or "lumps").  For larger sections
of documentation, including diagrams, I used separate text files that
were contained within the source code tree and processed by doxygen, but
without any code (except examples and the like).

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


#99639

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-16 11:43 +0000
Message-ID<o30jtg$bhm$1@dont-email.me>
In reply to#99632
On 16/12/16 11:10, David Brown wrote:
> On 16/12/16 00:27, Richard Heathfield wrote:
>> On 15/12/16 22:20, David Brown wrote:
>>> On 15/12/16 16:37, Richard Heathfield wrote:
>>
>> <snip>
>>
>>>> Module, right? Well, we have to say what we mean by "module". We might
>>>> reasonably define it as a source and its associated header, in which
>>>> case I think your point is fine.
>>>
>>> Yes, that is what I was meaning by "module".  Of course you are correct
>>> that I should have defined it - especially as it could mean other things.
>>>
>>>> But we might also define it as a set of
>>>> related functions, which might be spread over several sources. If we
>>>> define it that way (and, frankly, I do), then it becomes reasonable to
>>>> think of a module as having two headers: one public, and one private.
>>>> The private header is shared across all the sources that go to make up
>>>> that module, and the public header is shared across other modules.
>>>
>>> Agreed.
>>>
>>> If you prefer to call this sort of multi-file "lump" a "module", what do
>>> you call a header/C file "lump" ?
>>
>> A lump. What else?
>>
>> The correct term is "preprocessing translation unit". PTU, anyone? But I
>> tend to eschew the P and stick to "translation unit" (which is actually
>> the correct term for what remains after preprocessing, but I'm not too
>> fussed about the difference except when arguing about the difference!).
>
> No, a translation unit (or compilation unit) is something different.

Er, no it isn't.

> If you have:
>
> widget.h	// Declarations for widget functions
> widget.c	// Implementation of widget functions
> game.c		// Uses widget functions
>
> Then widget.c + any files it #include's (hopefully including widget.h)
> is a translation unit.

Yep. Dat what I said.

> So is game.c + any files /it/ includes
> (including widget.h).

Dat what I said, too.

> I am wondering what you call the lump "widget.h + widget.c", if
> anything?

Oh, you mean sans otherwidget.h and stdio.h and so on? Uh, I don't have 
a name for that. I don't /need/ a name for that.

> Maybe it is just a "module" that happens to contain only two
> files.

Oh, sure. Sorry, was that not clear? It's amazing how tangled these 
discussions can be come when we don't spell everything out. Yes, I am 
perfectly content to have a module consisting of just one C file and its 
header. But I am /also/ perfectly content for the module to have more 
than one C file.

I'm not terribly interested in linkers so I don't know whether this has 
changed, but they didn't used to be terribly bright, and they couldn't 
pull in just one function from an object file even if only one were 
used; they had to pull in the whole file. So, when space was so terribly 
important (and no doubt it still is for many people), C programmers 
would sometimes put each function in its own source file, even if there 
was a clear relationship existing amongst a bunch of those functions. In 
those circumstances, to call each one a module when, actually, it was 
the whole bunch of them that was really the module, would have seemed a 
bit silly.

<snip>

> The best is to write self-documenting code - then it is never out of
> sync.  At least, don't write anything in comments that could be
> expressed in code (such as by good choice of function and parameter names).

Yes.

>>> or
>>> simply not having the document at hand when you are working with the
>>> code.  Documentation in the header file is /always/ quickly at hand when
>>> you are working with the code!
>>
>> As long as you know the code well enough to know where to look, or know
>> what you're looking for well enough to execute a grep. External docs can
>> cover several headers in one indexed document. They can offer hyperlinks
>> to specific function descriptions, they can contain diagrams (and I
>> don't mean ASCII art), and they can use all the tricks of the word
>> processing trade to make the document more readable than can generally
>> be managed in eighty columns of Courier 12.
>>
>
> Some of use have moved to using more capable IDE's for their development
> work...

You have an IDE that's more capable than Linux? I'm impressed!

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99645

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-16 14:01 +0100
Message-ID<o30ohi$rcr$1@dont-email.me>
In reply to#99639
On 16/12/16 12:43, Richard Heathfield wrote:
> On 16/12/16 11:10, David Brown wrote:
>> On 16/12/16 00:27, Richard Heathfield wrote:
>>> On 15/12/16 22:20, David Brown wrote:
>>>> On 15/12/16 16:37, Richard Heathfield wrote:
>>>
<snip>
> 
> Oh, sure. Sorry, was that not clear? It's amazing how tangled these
> discussions can be come when we don't spell everything out. Yes, I am
> perfectly content to have a module consisting of just one C file and its
> header. But I am /also/ perfectly content for the module to have more
> than one C file.

It is untangled now, I think.

> 
> I'm not terribly interested in linkers so I don't know whether this has
> changed, but they didn't used to be terribly bright, and they couldn't
> pull in just one function from an object file even if only one were
> used; they had to pull in the whole file. So, when space was so terribly
> important (and no doubt it still is for many people), C programmers
> would sometimes put each function in its own source file, even if there
> was a clear relationship existing amongst a bunch of those functions. In
> those circumstances, to call each one a module when, actually, it was
> the whole bunch of them that was really the module, would have seemed a
> bit silly.

Linkers are a bit brighter now, especially along with smarter compilers.
 A common usage (in embedded systems, where space often is tight) is to
use "function sections" in the compiler so that each function is put
into its own little code section.  On the linker, you enable "garbage
collection" (a poor choice of name for the feature, I think) which
collects all the code sections which are reachable from critical code
such as main(), the reset handler, interrupt functions, etc.  Sections
are joined up as graphs, and anything left on its own island
disconnected from the main()land get thrown out.

Even smarter linkers work with the compiler for link-time optimisation,
but that's another story.

For my own coding, I can usually put all the related files into a single
C file - so two-file modules are the norm for me.  But then, I don't
often have functions defined that are not going to be part of the final
program - and if I do, "function sections" keep the output tidy.

> 
> <snip>
> 
>> The best is to write self-documenting code - then it is never out of
>> sync.  At least, don't write anything in comments that could be
>> expressed in code (such as by good choice of function and parameter
>> names).
> 
> Yes.
> 
>>>> or
>>>> simply not having the document at hand when you are working with the
>>>> code.  Documentation in the header file is /always/ quickly at hand
>>>> when
>>>> you are working with the code!
>>>
>>> As long as you know the code well enough to know where to look, or know
>>> what you're looking for well enough to execute a grep. External docs can
>>> cover several headers in one indexed document. They can offer hyperlinks
>>> to specific function descriptions, they can contain diagrams (and I
>>> don't mean ASCII art), and they can use all the tricks of the word
>>> processing trade to make the document more readable than can generally
>>> be managed in eighty columns of Courier 12.
>>>
>>
>> Some of use have moved to using more capable IDE's for their development
>> work...
> 
> You have an IDE that's more capable than Linux? I'm impressed!
> 

I have an IDE that can display more than eighty columns, open several
files at once, and even choose different fonts (it won't let me pick
Courier 12, however).

Of course, those big files and long lines are a pain when you need to
fix things via a mobile telephone, JuiceSSH, and nano editor - but
fortunately I haven't had to do that very often.

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


#99647

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-12-16 13:12 +0000
Message-ID<o30p5p$tg2$1@dont-email.me>
In reply to#99645
On 16/12/16 13:01, David Brown wrote:
> On 16/12/16 12:43, Richard Heathfield wrote:
>> On 16/12/16 11:10, David Brown wrote:
>>> On 16/12/16 00:27, Richard Heathfield wrote:

<snip>

>>>> As long as you know the code well enough to know where to look, or know
>>>> what you're looking for well enough to execute a grep. External docs can
>>>> cover several headers in one indexed document. They can offer hyperlinks
>>>> to specific function descriptions, they can contain diagrams (and I
>>>> don't mean ASCII art), and they can use all the tricks of the word
>>>> processing trade to make the document more readable than can generally
>>>> be managed in eighty columns of Courier 12.
>>>>
>>>
>>> Some of use have moved to using more capable IDE's for their development
>>> work...
>>
>> You have an IDE that's more capable than Linux? I'm impressed!
>>
>
> I have an IDE that can display more than eighty columns, open several
> files at once, and even choose different fonts (it won't let me pick
> Courier 12, however).

Well, of course I do too, but I /choose/ to keep my code display quite 
traditional because I find it easier to work that way. Does your text 
editor allow you to put hyperlinks in the code without changing the code 
itself? If so, I'm impressed. And can your text editor also display 
pixel-perfect (i.e. not just ASCII art) diagrams? If so, I'm even more 
impressed.

> Of course, those big files and long lines are a pain when you need to
> fix things via a mobile telephone, JuiceSSH, and nano editor - but
> fortunately I haven't had to do that very often.

That's what cars (and trains and boats and planes) are for.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#99650

FromDavid Brown <david.brown@hesbynett.no>
Date2016-12-16 14:57 +0100
Message-ID<o30rq6$77o$1@dont-email.me>
In reply to#99647
On 16/12/16 14:12, Richard Heathfield wrote:
> On 16/12/16 13:01, David Brown wrote:
>> On 16/12/16 12:43, Richard Heathfield wrote:
>>> On 16/12/16 11:10, David Brown wrote:
>>>> On 16/12/16 00:27, Richard Heathfield wrote:
> 
> <snip>
> 
>>>>> As long as you know the code well enough to know where to look, or
>>>>> know
>>>>> what you're looking for well enough to execute a grep. External
>>>>> docs can
>>>>> cover several headers in one indexed document. They can offer
>>>>> hyperlinks
>>>>> to specific function descriptions, they can contain diagrams (and I
>>>>> don't mean ASCII art), and they can use all the tricks of the word
>>>>> processing trade to make the document more readable than can generally
>>>>> be managed in eighty columns of Courier 12.
>>>>>
>>>>
>>>> Some of use have moved to using more capable IDE's for their
>>>> development
>>>> work...
>>>
>>> You have an IDE that's more capable than Linux? I'm impressed!
>>>
>>
>> I have an IDE that can display more than eighty columns, open several
>> files at once, and even choose different fonts (it won't let me pick
>> Courier 12, however).
> 
> Well, of course I do too, but I /choose/ to keep my code display quite
> traditional because I find it easier to work that way. Does your text
> editor allow you to put hyperlinks in the code without changing the code
> itself? If so, I'm impressed. And can your text editor also display
> pixel-perfect (i.e. not just ASCII art) diagrams? If so, I'm even more
> impressed.
> 

I think we have had one of those tangles again...  I meant that my IDE
(Eclipse) can make files more readable than you get with 80 columns
Courier 12, not that it can do everything you would want from a full
documentation system.  (To be a smart-ass - yes, I can put hyperlinks in
the code without changing the code itself.  I just type them in
comments.  But they are not clickable links, which I suspect is what you
meant.)

I am sure there are editors that /can/ show pictures and hyperlinks -
especially those geared more towards web development than C coding.  And
Eclipse can show all sorts of graphics stuff too - I only use a tiny
fraction of its features.

>> Of course, those big files and long lines are a pain when you need to
>> fix things via a mobile telephone, JuiceSSH, and nano editor - but
>> fortunately I haven't had to do that very often.
> 
> That's what cars (and trains and boats and planes) are for.
> 

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


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

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


csiph-web