Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What am I doing wrong?

3 views
Skip to first unread message

Cromulent

unread,
Jul 5, 2008, 9:22:41 PM7/5/08
to
I think I know what the problem is. I'm passing an array to strdup()
which is not what it wants and is producing a bus error. But, even
knowing the cause of the problem I'm having difficulties thinking of a
suitable solution.

I'm basically reading a CSV file and then tokenising it to get the
relevant values in a useable form. So I need to read the file one line
at a time in order to tokenise each one and put the values in the
correct place but I can't think of a way off the top of my head to read
a single line at a time using a function which would put it in a
malloced char*.

Here is the code.

int tokeniseInput(char readstring[])
{
char *cp;
const char delimiters[] = " ,'\n'";

proc = readstring;

smStrings *stockmarket;

cp = strdup(readstring);

stockmarket->smsdate = strtok(cp, delimiters);
printf("process1 = %s\n", stockmarket->smsdate);
stockmarket->smsopen = strtok(NULL, delimiters);
printf("process2 = %s\n", stockmarket->smsopen);
stockmarket->smshigh = strtok(NULL, delimiters);
printf("process3 = %s\n", stockmarket->smshigh);
stockmarket->smslow = strtok(NULL, delimiters);
printf("process4 = %s\n", stockmarket->smslow);
stockmarket->smsclose = strtok(NULL, delimiters);
printf("process5 = %s\n", stockmarket->smsclose);
stockmarket->smsvolume = strtok(NULL, delimiters);
printf("process6 = %s\n", stockmarket->smsvolume);

return 0;
}

--
"I disapprove of what you say, but I'll defend to the death your right
to say it." - Voltaire

Cromulent

unread,
Jul 5, 2008, 9:25:09 PM7/5/08
to
On 2008-07-06 02:22:41 +0100, Cromulent <crom...@justextrememetal.com> said:

> proc = readstring;

Bah, ignore this bit. I deleted it from my code after I copied it to my
post and forgot to delete it.

Ben Bacarisse

unread,
Jul 5, 2008, 10:16:23 PM7/5/08
to
Cromulent <crom...@justextrememetal.com> writes:

> I think I know what the problem is. I'm passing an array to strdup()

No you are not despite appearances.

> which is not what it wants and is producing a bus error. But, even
> knowing the cause of the problem I'm having difficulties thinking of a
> suitable solution.
>
> I'm basically reading a CSV file and then tokenising it to get the
> relevant values in a useable form. So I need to read the file one line
> at a time in order to tokenise each one and put the values in the
> correct place but I can't think of a way off the top of my head to
> read a single line at a time using a function which would put it in a
> malloced char*.

You don't need to read one line at a time. In fact that can make the
parsing of a CSV file harder (or at least, it can fail to make it
simple).

> Here is the code.
>
> int tokeniseInput(char readstring[])

readstring is a pointer despite the []. C can't pass arrays and
rather than forbid this syntax it was taken to mean the same as char
*readstring in the context.

> {
> char *cp;
> const char delimiters[] = " ,'\n'";

Odd. You know you have two 's in there? ' is not even special in CSV
files as far as I know.

> proc = readstring;

OK, ignoring this as per you other message.

> smStrings *stockmarket;

Not pointing anywhere. Using it with -> will cause undefined behaviour.

> cp = strdup(readstring);

You will get a memory leak if you don't record the cp pointer
somewhere (it won't always be returned by the first call to strtok).
Without it you can't free the memory, ever.

> stockmarket->smsdate = strtok(cp, delimiters);

Bang! stockmarket->smsdate is undefined unless stockmarket has been
made to point to the right sort of thing.

> printf("process1 = %s\n", stockmarket->smsdate);
> stockmarket->smsopen = strtok(NULL, delimiters);
> printf("process2 = %s\n", stockmarket->smsopen);
> stockmarket->smshigh = strtok(NULL, delimiters);
> printf("process3 = %s\n", stockmarket->smshigh);
> stockmarket->smslow = strtok(NULL, delimiters);
> printf("process4 = %s\n", stockmarket->smslow);
> stockmarket->smsclose = strtok(NULL, delimiters);
> printf("process5 = %s\n", stockmarket->smsclose);
> stockmarket->smsvolume = strtok(NULL, delimiters);
> printf("process6 = %s\n", stockmarket->smsvolume);

This will only work if your input is very simple. The slightest
unexpected thing like an empty field or a comma in a field and it all
goes haywire.

> return 0;
> }

--
Ben.

Cromulent

unread,
Jul 5, 2008, 10:49:04 PM7/5/08
to
On 2008-07-06 03:16:23 +0100, Ben Bacarisse <ben.u...@bsb.me.uk> said:

> Cromulent <crom...@justextrememetal.com> writes:
>
>> Here is the code.
>>
>> int tokeniseInput(char readstring[])
>
> readstring is a pointer despite the []. C can't pass arrays and
> rather than forbid this syntax it was taken to mean the same as char
> *readstring in the context.

Ah, I see thanks.

>
>> {
>> char *cp;
>> const char delimiters[] = " ,'\n'";
>
> Odd. You know you have two 's in there? ' is not even special in CSV
> files as far as I know.

Ah I meant it to be '\n' not ' and \n if that makes sense. They were
meant to be enclosing the newline character as I was not sure if it was
needed or not. I guess not.

>
>> smStrings *stockmarket;
>
> Not pointing anywhere. Using it with -> will cause undefined behaviour.

How do you mean? It points to a typedefed struct which is declared in
the header file.

>
>> cp = strdup(readstring);
>
> You will get a memory leak if you don't record the cp pointer
> somewhere (it won't always be returned by the first call to strtok).
> Without it you can't free the memory, ever.

Ah. Good catch, I need to fix that up then.

>
>> stockmarket->smsdate = strtok(cp, delimiters);
>
> Bang! stockmarket->smsdate is undefined unless stockmarket has been
> made to point to the right sort of thing.
>
>> printf("process1 = %s\n", stockmarket->smsdate);
>> stockmarket->smsopen = strtok(NULL, delimiters);
>> printf("process2 = %s\n", stockmarket->smsopen);
>> stockmarket->smshigh = strtok(NULL, delimiters);
>> printf("process3 = %s\n", stockmarket->smshigh);
>> stockmarket->smslow = strtok(NULL, delimiters);
>> printf("process4 = %s\n", stockmarket->smslow);
>> stockmarket->smsclose = strtok(NULL, delimiters);
>> printf("process5 = %s\n", stockmarket->smsclose);
>> stockmarket->smsvolume = strtok(NULL, delimiters);
>> printf("process6 = %s\n", stockmarket->smsvolume);
>
> This will only work if your input is very simple. The slightest
> unexpected thing like an empty field or a comma in a field and it all
> goes haywire.

It is just stock market data downloaded from Google Finance. No real
chance of any funny input. But I see your point.

Richard Heathfield

unread,
Jul 5, 2008, 11:11:44 PM7/5/08
to
Ben Bacarisse said:

> Cromulent <crom...@justextrememetal.com> writes:
>
<snip>


>>
>> int tokeniseInput(char readstring[])
>
> readstring is a pointer despite the []. C can't pass arrays and
> rather than forbid this syntax it was taken to mean the same as char
> *readstring in the context.

No, that wasn't the reason, as a matter of fact. In the early days of C,
pointers were described using [] rather than *. It wasn't long before the
* was introduced, at which point [] was used exclusively for arrays,
*except* in this situation - i.e. a function receiving a pointer as a
parameter. Just why it was retained, I don't know - possibly a nod in the
direction of backwards compatibility.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Ian Collins

unread,
Jul 5, 2008, 11:09:07 PM7/5/08
to
Cromulent wrote:
> On 2008-07-06 03:16:23 +0100, Ben Bacarisse <ben.u...@bsb.me.uk> said:
>
>> Cromulent <crom...@justextrememetal.com> writes:
>>
>>> smStrings *stockmarket;
>>
>> Not pointing anywhere. Using it with -> will cause undefined behaviour.
>
> How do you mean? It points to a typedefed struct which is declared in
> the header file.
>
Not in the code you posted it doesn't. You just declare the pointer,
you don't assign any value to it.

--
Ian Collins.

Cromulent

unread,
Jul 5, 2008, 11:33:00 PM7/5/08
to

Yes, I see now. 4.30am here and I'm a tad tired :).

So I've changed it to the following:

smStrings *stockStrings = malloc(sizeof(smStrings));

Ian Collins

unread,
Jul 5, 2008, 11:39:36 PM7/5/08
to
Cromulent wrote:
> On 2008-07-06 04:09:07 +0100, Ian Collins <ian-...@hotmail.com> said:
>
>> Cromulent wrote:
>>> On 2008-07-06 03:16:23 +0100, Ben Bacarisse <ben.u...@bsb.me.uk> said:
>>>
>>>> Cromulent <crom...@justextrememetal.com> writes:
>>>>
>>>>> smStrings *stockmarket;
>>>>
>>>> Not pointing anywhere. Using it with -> will cause undefined
>>>> behaviour.
>>>
>>> How do you mean? It points to a typedefed struct which is declared in
>>> the header file.
>>>
>> Not in the code you posted it doesn't. You just declare the pointer,
>> you don't assign any value to it.
>
> Yes, I see now. 4.30am here and I'm a tad tired :).
>
Every hour spent coding while tired adds two to the job fixing the bugs!

--
Ian Collins.

Barry Schwarz

unread,
Jul 6, 2008, 12:41:52 AM7/6/08
to
On Sun, 6 Jul 2008 02:22:41 +0100, Cromulent
<crom...@justextrememetal.com> wrote:

>I think I know what the problem is. I'm passing an array to strdup()
>which is not what it wants and is producing a bus error. But, even
>knowing the cause of the problem I'm having difficulties thinking of a
>suitable solution.

The real error is not in the code you posted. You need to provide a
complete compilable program that demonstrates the undesired behavior.

>
>I'm basically reading a CSV file and then tokenising it to get the
>relevant values in a useable form. So I need to read the file one line
>at a time in order to tokenise each one and put the values in the
>correct place but I can't think of a way off the top of my head to read
>a single line at a time using a function which would put it in a
>malloced char*.

Look up fgets in your reference.


Remove del for email

Mark McIntyre

unread,
Jul 6, 2008, 5:55:45 AM7/6/08
to
Cromulent wrote:
> ?? smStrings *stockmarket;

>>
>> Not pointing anywhere. Using it with -> will cause undefined behaviour.
>
> How do you mean? It points to a typedefed struct which is declared in
> the header file.

stockmarket is a pointer. But it isn't pointing AT anything.
You need to allocate some memory for the object.

>> This will only work if your input is very simple. The slightest
>> unexpected thing like an empty field or a comma in a field and it all
>> goes haywire.
>
> It is just stock market data downloaded from Google Finance. No real
> chance of any funny input. But I see your point.

:-) I like your optimism in the accuracy of google!

You may want to consider what happens when they add/delete/change a
column however.


--
Mark McIntyre

CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

Cromulent

unread,
Jul 6, 2008, 7:33:24 AM7/6/08
to
On 2008-07-06 05:41:52 +0100, Barry Schwarz <schw...@dqel.com> said:
>
>>
>> I'm basically reading a CSV file and then tokenising it to get the
>> relevant values in a useable form. So I need to read the file one line
>> at a time in order to tokenise each one and put the values in the
>> correct place but I can't think of a way off the top of my head to read
>> a single line at a time using a function which would put it in a
>> malloced char*.
>
> Look up fgets in your reference.
>

That is what I use already.

santosh

unread,
Jul 6, 2008, 8:38:31 AM7/6/08
to
Cromulent wrote:

> On 2008-07-06 05:41:52 +0100, Barry Schwarz <schw...@dqel.com> said:
>>
>>>
>>> I'm basically reading a CSV file and then tokenising it to get the
>>> relevant values in a useable form. So I need to read the file one
>>> line at a time in order to tokenise each one and put the values in
>>> the correct place but I can't think of a way off the top of my head
>>> to read a single line at a time using a function which would put it
>>> in a malloced char*.
>>
>> Look up fgets in your reference.
>>
>
> That is what I use already.

If you want a function that will read in arbitrarily long lines (your
comment about "malloced char*" seems to suggest so), then try one of
the functions discussed at the following page. It's also easy enough to
write your own version also.

<http://www.cpax.org.uk/prg/writings/fgetdata.php>

Cromulent

unread,
Jul 6, 2008, 9:10:47 AM7/6/08
to

This is the code I have at the moment for my readline function, it is
just a slightly modified version of a function in K&R2. The only
problem is that limit needs to be set arbitarily high which is wasteful.

int readLine(FILE *fp, int limit, char readstring[], smStrings *stockmarket)
{
int x = 0, i = 0;

for(i = 0; i < limit -1 && (x = fgetc(fp)) != EOF && x != '\n'; ++i)
{
readstring[i] = x;
if(readstring[i] == '\n')
{
readstring[i] = x;
++i;
}
}

readstring[i] = '\0';

printf("%s\n", readstring);

tokeniseInput(readstring, stockmarket);

return i;
}

I'll have a look through that article and code you posted. It certainly
looks interesting.

I do however get the impression that my code is incredibly immature
when I read this usenet group. I keep missing out on tricks through
lack of knowledge, especially when it involves pointers to pointers.

santosh

unread,
Jul 6, 2008, 9:25:05 AM7/6/08
to
Cromulent wrote:

<snip>

> This is the code I have at the moment for my readline function, it is
> just a slightly modified version of a function in K&R2. The only
> problem is that limit needs to be set arbitarily high which is
> wasteful.
>
> int readLine
> (FILE *fp, int limit, char readstring[], smStrings *stockmarket)
> {
> int x = 0, i = 0;

You might want to consider using unsigned long for limit. This will
allow the loop to read more than 65535 characters. As written your
limit is 32767 characters.

> for(i = 0;
> i < limit -1 && (x = fgetc(fp)) != EOF && x != '\n';
> ++i) {
> readstring[i] = x;
> if(readstring[i] == '\n')

This condition can never be true, since execution will never enter the
loop if fgetc had returned a '\n' character.

> {
> readstring[i] = x;
> ++i;
> }
> }
> readstring[i] = '\0';
> printf("%s\n", readstring);
> tokeniseInput(readstring, stockmarket);
> return i;
> }

<snip>

Cromulent

unread,
Jul 6, 2008, 10:20:31 AM7/6/08
to
On 2008-07-06 14:55:05 +0100, santosh <santo...@gmail.com> said:

> Cromulent wrote:
>
>> for(i = 0;
>> i < limit -1 && (x = fgetc(fp)) != EOF && x != '\n';
>> ++i) {
>> readstring[i] = x;
>> if(readstring[i] == '\n')
>
> This condition can never be true, since execution will never enter the
> loop if fgetc had returned a '\n' character.

Hmm, I was under the impression that x must at some point = '\n' in
order for the evaluation of != '\n' to be decided. At what point is the
'\n' discarded from x?

Cromulent

unread,
Jul 6, 2008, 10:37:11 AM7/6/08
to
On 2008-07-06 15:20:31 +0100, Cromulent <crom...@justextrememetal.com> said:
>
> Hmm, I was under the impression that x must at some point = '\n' in
> order for the evaluation of != '\n' to be decided. At what point is the
> '\n' discarded from x?

Bah, ignore this comment. Just realised the mistake, of course it just
exits the loop completely when it evaluates != '\n' to be false.

Why do I only realise these simple mistakes when I have a ciggy? I need
more tea.

Ben Bacarisse

unread,
Jul 6, 2008, 12:10:05 PM7/6/08
to
Richard Heathfield <r...@see.sig.invalid> writes:

> Ben Bacarisse said:
>
>> Cromulent <crom...@justextrememetal.com> writes:
>>
> <snip>
>>>
>>> int tokeniseInput(char readstring[])
>>
>> readstring is a pointer despite the []. C can't pass arrays and
>> rather than forbid this syntax it was taken to mean the same as char
>> *readstring in the context.
>
> No, that wasn't the reason, as a matter of fact. In the early days of C,
> pointers were described using [] rather than *. It wasn't long before the
> * was introduced, at which point [] was used exclusively for arrays,
> *except* in this situation - i.e. a function receiving a pointer as a
> parameter. Just why it was retained, I don't know - possibly a nod in the
> direction of backwards compatibility.

That's an interesting bit of history but it does not contradict
anything I said. Image an historically accurate parenthetical remark
"(when the * syntax was introduced to declare pointers)" between "and"
and "rather". In other words, thank you for adding the context I left
out, but did you have to start your answer with the word "no"?

--
Ben.

Barry Schwarz

unread,
Jul 6, 2008, 1:53:06 PM7/6/08
to
On Sun, 6 Jul 2008 12:33:24 +0100, Cromulent
<crom...@justextrememetal.com> wrote:

>On 2008-07-06 05:41:52 +0100, Barry Schwarz <schw...@dqel.com> said:
>>
>>>
>>> I'm basically reading a CSV file and then tokenising it to get the
>>> relevant values in a useable form. So I need to read the file one line
>>> at a time in order to tokenise each one and put the values in the
>>> correct place but I can't think of a way off the top of my head to read
>>> a single line at a time using a function which would put it in a
>>> malloced char*.
>>
>> Look up fgets in your reference.
>>
>
>That is what I use already.

Strange. There was not a single call to fgets in your original post.
In fact, there was no input routine at all. And in a subsequent post
that contains your readLine function, you use fgetc, not fgets.

I wonder where you think you are using fgets. And if you are using
fgets, why do think it doesn't provide an solution to your original
question about reading a line at a time?


Remove del for email

Cromulent

unread,
Jul 6, 2008, 2:15:09 PM7/6/08
to

Whoops. I misread that as fgetc not fgets. In that case I stand
corrected. Fairly easy mistake to make.

Richard Heathfield

unread,
Jul 6, 2008, 3:53:27 PM7/6/08
to
Ben Bacarisse said:

> Richard Heathfield <r...@see.sig.invalid> writes:
>
>> Ben Bacarisse said:
>>
>>> Cromulent <crom...@justextrememetal.com> writes:
>>>
>> <snip>
>>>>
>>>> int tokeniseInput(char readstring[])
>>>
>>> readstring is a pointer despite the []. C can't pass arrays and
>>> rather than forbid this syntax it was taken to mean the same as char
>>> *readstring in the context.
>>
>> No, that wasn't the reason, as a matter of fact. In the early days of C,
>> pointers were described using [] rather than *. It wasn't long before
>> the * was introduced, at which point [] was used exclusively for arrays,
>> *except* in this situation - i.e. a function receiving a pointer as a
>> parameter. Just why it was retained, I don't know - possibly a nod in
>> the direction of backwards compatibility.
>
> That's an interesting bit of history but it does not contradict
> anything I said.

Then I must have misunderstood what you said.

<snip>

Joe Wright

unread,
Jul 6, 2008, 4:09:55 PM7/6/08
to

Do you agree that ..

member,first,mi,last,dob,eff_date,exp_date
1,John,,Doe,07/04/1776,01/01/1800,
2,Mack,T,Knife,11/11/1918,10/1/1939,5/25/2005

.. might be the contents of your CSV file?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

Cromulent

unread,
Jul 6, 2008, 4:13:47 PM7/6/08
to
On 2008-07-06 21:09:55 +0100, Joe Wright <joeww...@comcast.net> said:
> Do you agree that ..
>
> member,first,mi,last,dob,eff_date,exp_date
> 1,John,,Doe,07/04/1776,01/01/1800,
> 2,Mack,T,Knife,11/11/1918,10/1/1939,5/25/2005
>
> .. might be the contents of your CSV file?

Err, no not really as that has nothing to do with stock market prices :).

Joe Wright

unread,
Jul 6, 2008, 5:11:48 PM7/6/08
to
Cromulent wrote:
> On 2008-07-06 21:09:55 +0100, Joe Wright <joeww...@comcast.net> said:
>> Do you agree that ..
>>
>> member,first,mi,last,dob,eff_date,exp_date
>> 1,John,,Doe,07/04/1776,01/01/1800,
>> 2,Mack,T,Knife,11/11/1918,10/1/1939,5/25/2005
>>
>> .. might be the contents of your CSV file?
>
> Err, no not really as that has nothing to do with stock market prices :).

Of course. I was talking about the format of the file. In the case of
Microsoft Excel, Visual FoxPro and perhaps Access, CSV files are text
representations of tables. The first row (line) of the CSV file are the
names of the columns and subsequent lines are the values of the columns.

Is this the kind of CSV file you are talking about or do you have some
other idea?

Cromulent

unread,
Jul 6, 2008, 5:44:55 PM7/6/08
to
On 2008-07-06 22:11:48 +0100, Joe Wright <joeww...@comcast.net> said:

> Cromulent wrote:
>> On 2008-07-06 21:09:55 +0100, Joe Wright <joeww...@comcast.net> said:
>>> Do you agree that ..
>>>
>>> member,first,mi,last,dob,eff_date,exp_date
>>> 1,John,,Doe,07/04/1776,01/01/1800,
>>> 2,Mack,T,Knife,11/11/1918,10/1/1939,5/25/2005
>>>
>>> .. might be the contents of your CSV file?
>>
>> Err, no not really as that has nothing to do with stock market prices :).
>
> Of course. I was talking about the format of the file. In the case of
> Microsoft Excel, Visual FoxPro and perhaps Access, CSV files are text
> representations of tables. The first row (line) of the CSV file are the
> names of the columns and subsequent lines are the values of the columns.
>
> Is this the kind of CSV file you are talking about or do you have some
> other idea?

Ah, I see. Yes that is exactly the type of data I will be using. Here
is an example:

Date,Open,High,Low,Close,Volume
3-Jul-08,0.80,1.09,0.80,1.09,77800
2-Jul-08,1.08,1.09,0.56,0.94,19600
1-Jul-08,1.09,1.09,0.95,1.08,29700
30-Jun-08,0.80,1.09,0.75,1.09,11500

Joe Wright

unread,
Jul 6, 2008, 7:06:09 PM7/6/08
to

Ok, thanks. I deal with these .csv files every day at my job. I haven't
used strtok() in twenty years, since I figured out how it works.

Given your example file, what do you want to do with the data?

Cromulent

unread,
Jul 6, 2008, 8:15:24 PM7/6/08
to
On 2008-07-07 00:06:09 +0100, Joe Wright <joeww...@comcast.net> said:
>
>>
>> Ah, I see. Yes that is exactly the type of data I will be using. Here
>> is an example:
>>
>> Date,Open,High,Low,Close,Volume
>> 3-Jul-08,0.80,1.09,0.80,1.09,77800
>> 2-Jul-08,1.08,1.09,0.56,0.94,19600
>> 1-Jul-08,1.09,1.09,0.95,1.08,29700
>> 30-Jun-08,0.80,1.09,0.75,1.09,11500
>
> Ok, thanks. I deal with these .csv files every day at my job. I haven't
> used strtok() in twenty years, since I figured out how it works.
>
> Given your example file, what do you want to do with the data?

Basically I want to split the component parts up. I want to keep the
date and convert it to a useable form and then take each of the other
components (open, high, low etc) and put them in the appropriate
variable type. Then once I have all of them I want to be able to do
certain mathmatically functions. To give a very simple example I want
to be able to work out the moving average with the given data.

CBFalconer

unread,
Jul 6, 2008, 10:05:35 PM7/6/08
to
Cromulent wrote:
> Joe Wright <joeww...@comcast.net> said:
>
>>> Ah, I see. Yes that is exactly the type of data I will be using.
>>> Here is an example:
>>>
>>> Date,Open,High,Low,Close,Volume
>>> 3-Jul-08,0.80,1.09,0.80,1.09,77800
>>> 2-Jul-08,1.08,1.09,0.56,0.94,19600
>>> 1-Jul-08,1.09,1.09,0.95,1.08,29700
>>> 30-Jun-08,0.80,1.09,0.75,1.09,11500
>>
>> Ok, thanks. I deal with these .csv files every day at my job. I
>> haven't used strtok() in twenty years, since I figured out how
>> it works.
>>
>> Given your example file, what do you want to do with the data?
>
> Basically I want to split the component parts up. I want to keep
> the date and convert it to a useable form and then take each of
> the other components (open, high, low etc) and put them in the
> appropriate variable type. Then once I have all of them I want to
> be able to do certain mathmatically functions. To give a very
> simple example I want to be able to work out the moving average
> with the given data.

Please do not strip attribution lines for material you quote.
Those are the initial lines of the form "Joe wrote:", and give
credit to the authors.

Try this:

/* ------- file tknsplit.c ----------*/
#include "tknsplit.h"

/* copy over the next tkn from an input string, after
skipping leading blanks (or other whitespace?). The
tkn is terminated by the first appearance of tknchar,
or by the end of the source string.

The caller must supply sufficient space in tkn to
receive any tkn, Otherwise tkns will be truncated.

Returns: a pointer past the terminating tknchar.

This will happily return an infinity of empty tkns if
called with src pointing to the end of a string. Tokens
will never include a copy of tknchar.

A better name would be "strtkn", except that is reserved
for the system namespace. Change to that at your risk.

released to Public Domain, by C.B. Falconer.
Published 2006-02-20. Attribution appreciated.
Revised 2006-06-13 2007-05-26 (name)
*/

const char *tknsplit(const char *src, /* Source of tkns */
char tknchar, /* tkn delimiting char */
char *tkn, /* receiver of parsed tkn */
size_t lgh) /* length tkn can receive */
/* not including final '\0' */
{
if (src) {
while (' ' == *src) src++;

while (*src && (tknchar != *src)) {
if (lgh) {
*tkn++ = *src;
--lgh;
}
src++;
}
if (*src && (tknchar == *src)) src++;
}
*tkn = '\0';
return src;
} /* tknsplit */

#ifdef TESTING
#include <stdio.h>

#define ABRsize 6 /* length of acceptable tkn abbreviations */

/* ---------------- */

static void showtkn(int i, char *tok)
{
putchar(i + '1'); putchar(':');
puts(tok);
} /* showtkn */

/* ---------------- */

int main(void)
{
char teststring[] = "This is a test, ,, abbrev, more";

const char *t, *s = teststring;
int i;
char tkn[ABRsize + 1];

puts(teststring);
t = s;
for (i = 0; i < 4; i++) {
t = tknsplit(t, ',', tkn, ABRsize);
showtkn(i, tkn);
}

puts("\nHow to detect 'no more tkns' while truncating");
t = s; i = 0;
while (*t) {
t = tknsplit(t, ',', tkn, 3);
showtkn(i, tkn);
i++;
}

puts("\nUsing blanks as tkn delimiters");
t = s; i = 0;
while (*t) {
t = tknsplit(t, ' ', tkn, ABRsize);
showtkn(i, tkn);
i++;
}
return 0;
} /* main */

#endif
/* ------- end file tknsplit.c ----------*/

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

Ben Bacarisse

unread,
Jul 7, 2008, 8:56:43 AM7/7/08
to
Cromulent <crom...@justextrememetal.com> writes:

> On 2008-07-07 00:06:09 +0100, Joe Wright <joeww...@comcast.net> said:
>>
>>>
>>> Ah, I see. Yes that is exactly the type of data I will be
>>> using. Here is an example:
>>>
>>> Date,Open,High,Low,Close,Volume
>>> 3-Jul-08,0.80,1.09,0.80,1.09,77800
>>> 2-Jul-08,1.08,1.09,0.56,0.94,19600
>>> 1-Jul-08,1.09,1.09,0.95,1.08,29700
>>> 30-Jun-08,0.80,1.09,0.75,1.09,11500
>>
>> Ok, thanks. I deal with these .csv files every day at my job. I
>> haven't used strtok() in twenty years, since I figured out how it
>> works.
>>
>> Given your example file, what do you want to do with the data?
>
> Basically I want to split the component parts up.

You could do a lot worse than simply using fscanf. If you make the
format quite strict and test the return you will be alerted to most
input errors:

char month[4], nl;
double open, hi, lo, close;
unsigned day, year, vol;
...
if (fscanf("%2u-%3s-%2u,%lf,%lf,%lf,%lf,%u%c",
&day, month, &year, &open, &hi, &lo, &close, &vol, &nl) == 9
&& nl == '\n')

--
Ben.

Bill Reid

unread,
Jul 7, 2008, 7:00:57 PM7/7/08
to

Bill Reid <horme...@happyhealthy.net> wrote in message
news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...

DAMN!!! I hate it when that happens!!!

> fgets(csv_line,512,file); /* again, skip the header */
> while(fgets(csv_line,512,file)!=NULL) {
> sscanf(csv_line,"%[^,],%d,%d,%d,%d\n",
> date_buf,
> &(curr_record.open),
> &(curr_record.high),
> &(curr_record.low),
> &(curr_record.close));
> /* I'll give you ideas how to convert the date to be "usable" later
*/
> /* basically:
> curr_record.date=get_date_from_string(date_buf,date_format); */
> curr_record++;
> }

Of course, the format string for sscanf() should really be:

"%[^,],%f,%f,%f,%f\n"

...in order to actually scan the double floating-point numbers
we declared in our t_ohlc_record struct (or equivalent format
specifiers. Sorry about that chief...

---
William Ernest Reid

Bill Reid

unread,
Jul 7, 2008, 6:52:53 PM7/7/08
to

Cromulent <crom...@justextrememetal.com> wrote in message
news:2008070701152416807-cromulent@justextrememetalcom...

> On 2008-07-07 00:06:09 +0100, Joe Wright <joeww...@comcast.net> said:
> >
> >> Ah, I see. Yes that is exactly the type of data I will be using. Here
> >> is an example:
> >>
> >> Date,Open,High,Low,Close,Volume
> >> 3-Jul-08,0.80,1.09,0.80,1.09,77800
> >> 2-Jul-08,1.08,1.09,0.56,0.94,19600
> >> 1-Jul-08,1.09,1.09,0.95,1.08,29700
> >> 30-Jun-08,0.80,1.09,0.75,1.09,11500
> >
> > Ok, thanks. I deal with these .csv files every day at my job. I haven't
> > used strtok() in twenty years, since I figured out how it works.

Also, in this case, it's a waste of time...

> > Given your example file, what do you want to do with the data?
>
> Basically I want to split the component parts up.

Well, probably not. You probably DON'T want to "split the
component parts up", per se...

> I want to keep the
> date and convert it to a useable form and then take each of the other
> components (open, high, low etc) and put them in the appropriate
> variable type.

OK, you're getting closer to what you REALLY want to do...

> Then once I have all of them I want to be able to do
> certain mathmatically functions. To give a very simple example I want
> to be able to work out the moving average with the given data.

Oh, don't say "moving average", that's beyond the understanding of
the regulars here. In any event, what you REALLY want to do is read
the data into memory in a "data table" struct specifically for "time series"
data tables something like this:

typedef struct time_series {
char data_name[NAMEMAX];
char record_type[NAMEMAX];
unsigned num_dates;
void *series;
} t_time_series;

Although for the time being you can probably dispense with the
added wrinkle of identifying the exact format of the data records you will
be working with, since you only have one so far:

typedef struct ohlc_record {
unsigned date;
double open;
double high;
double low;
double close;
} t_ohlc_record;

typedef struct ohlc_table {
char symbol[NAMEMAX];
unsigned num_dates;
t_ohlc_record *dates;
} t_ohlc_table;

See where we're going here? Every time you want to work with this
data, you will read your CSV file data into a malloc'ed array of type
t_ohlc_record, assign the pointer to your t_ohlc_table *dates pointer,
and assign the total number of dates in the file to num_dates, and
copy the string identifying the stock to symbol.

Since this is a very simple CSV file with small relatively-unvarying
line sizes, all you need to read it is fgets() and sscanf() in simple
loops after opening the file. DON'T LISTEN TO THE REGULARS
HERE ABOUT "STANDARD" CSV FORMATS, MALFORMED
FORMATS, "DYNAMIC" MALLOC ROUTINES, ANAL-RETENTIVE
ERROR-CHECKING, ETC., IF YOU EVER WANT TO GET THIS
VERY SIMPLE JOB DONE.

Just declare a static char array buffer of like 512 bytes, which is
about 10 times oversize for this job, and your t_ohlc_table object,
and also a little char buffer for your date, and a t_ohlc_record
pointer variable:

static char csv_line[512];
static t_ohlc_table ohlc_table;
static char date_buf[32];
t_ohlc_record *curr_record;

Then, write a "read_ohlc_csv()" function, where you open the file,
and first loop through the entire file to find how many dates are in the
file based on the number of "newlines":

fgets(csv_line,512,file); /* skip the header, right? */
while(fgets(csv_line,512,file)!=NULL)
ohlc_table.num_dates++;

Then malloc() your array of t_ohlc_record, based on sizeof(t_ohlc_record)
times ohlc_table.num_dates, and assign the pointer to ohlc_table.dates.

Then rewind() the file, and loop through it again to assign the
ohlc_record for each date.

curr_record=ohlc_table.dates;

fgets(csv_line,512,file); /* again, skip the header */
while(fgets(csv_line,512,file)!=NULL) {
sscanf(csv_line,"%[^,],%d,%d,%d,%d\n",
date_buf,
&(curr_record.open),
&(curr_record.high),
&(curr_record.low),
&(curr_record.close));
/* I'll give you ideas how to convert the date to be "usable" later */
/* basically:
curr_record.date=get_date_from_string(date_buf,date_format); */
curr_record++;
}

Then close your file, and you're ready to roll! You can now loop through
your entire "data table" and calculate your moving average based on the
close if that's what blows up your skirt, whatever you want. Just remember
to free() the memory you malloc'ed for the "table" when you're through.

OK, about "usable dates", it really helps if you have a nice library of
date functions to handle the conversion of a date string in a particular
format to an unsigned integer (I use an unsigned integer to represent dates
in a very simple specific way in my library, though it does suffer from a
"year 40,9600 problem", or even worse, a "year 21,2700 problem" depending
on how atoi() handles signed/unsigned overflow, but I suspect I'll have a
64-bit machine by then and will re-compile). In any event, once you have
a "usable" date, I would recommend you re-write your file to use
THAT date format rather than the Google(TM) format.

That's because ANSI C has some functions that format date and time
strings, but it lacks the ability to scan a date string and return a
numeric date. My date-time library does the conversion both ways, using
a common set of mnemonic date formats covering about 85 different date
formats. To convert the string in the format you're dealing with,
you're gonna have to set up an array of month abbreviations, and loop
through the array until you hit the one you're looking for, then
you return the array position (or position+1) as your month integer,
and of course you can use sscanf() to get the year and the date.
Then you can put the numbers together in a "usable" numeric format
for quick comparisons of greater and lesser dates.

You're in luck today on the topic of CSV files, because the topic of
writing "software" to handle "groups" of stocks came up on
misc.invest.stocks
in the last few days, and I wound up writing a whole stupid dissertation on
the topic and the beginnings of "C" program to perform portfolio management,
because I didn't have anything better to do for a few hours. There are many
similarities between what you want to do and this little program, so you
might
want to use the following for "ideas", since it specifically reads (and
writes)
simple CSV files like you are dealing with, and illustrates my particular
date format.

The following is a simple
CSV file, a header file, and two "C" files, and you should be able to
copy them to a directory and compile/link and see how the whole thing works,
and maybe modify it for your own purposes:

-------------
portfolio.txt
-------------
"Ticker","Date Bought","Date Sold"
SIRI,20070102,20080103
GCOG,20070102,0

------------
portfolios.h
------------
#ifndef portfoliosH
#define portfoliosH

#define TICKERMAX 32

typedef struct position {
char ticker[TICKERMAX];
unsigned date_bought;
unsigned date_sold;
} t_position;

typedef struct portfolio {
unsigned num_positions;
t_position *positions;
} t_portfolio;

#ifdef __cplusplus
extern "C" {
#endif

void free_portfolio(t_portfolio *);
void view_portfolio(t_portfolio *);
t_portfolio *read_portfolio(char *);
unsigned save_portfolio(t_portfolio *,char *);

#ifdef __cplusplus
}
#endif

#endif

------------
portfolios.c
------------
#include <stdio.h>
#include <stdlib.h>

#include "portfolios.h"

#define LINEMAX 512

char lib_csv_line[LINEMAX];

void free_portfolio(t_portfolio *portfolio) {

if(portfolio!=NULL) {
if(portfolio->positions!=NULL)
free(portfolio->positions);

free(portfolio);
portfolio=NULL;
}
}

void view_portfolio(t_portfolio *portfolio) {
t_position *position;

printf("\nThere are %d positions in the portfolio\n",
portfolio->num_positions);

position=portfolio->positions;
while(*position->ticker!='\0') {
printf("%s bought %d, sold %d\n",
position->ticker,
position->date_bought,
position->date_sold);
position++;
}
}

t_portfolio *read_portfolio(char *filepath) {
FILE *file;
t_portfolio *portfolio=NULL;
t_position *position;

if((file=fopen(filepath,"r"))==NULL) {
printf("\nError: failed to open portfolio file\n%s\n",filepath);
return portfolio;
}

if((portfolio=malloc(sizeof(t_portfolio)))==NULL) {
printf("\nError: not enough memory for portfolio\n");
fclose(file);
return portfolio;
}

portfolio->num_positions=0;
portfolio->positions=NULL;

fgets(lib_csv_line,LINEMAX,file);
while(fgets(lib_csv_line,LINEMAX,file)!=NULL)
portfolio->num_positions++;

if((portfolio->positions=
malloc((portfolio->num_positions+1)*sizeof(t_position)))==NULL) {
printf("\nError: not enough memory for portfolio positions\n");
free_portfolio(portfolio);
fclose(file);
return portfolio;
}

rewind(file);

position=portfolio->positions;
fgets(lib_csv_line,LINEMAX,file);
while(fgets(lib_csv_line,LINEMAX,file)!=NULL) {
sscanf(lib_csv_line,"%[^,],%d,%d\n",
position->ticker,
&(position->date_bought),
&(position->date_sold));
position++;
}

*position->ticker='\0';

fclose(file);

return portfolio;
}

unsigned save_portfolio(t_portfolio *portfolio,char *filepath) {
FILE *file;
t_position *position=portfolio->positions;

if((file=fopen(filepath,"w"))==NULL) {
printf("\nError: failed to open portfolio file %s",filepath);
return 0;
}

fputs("\"Ticker\",\"Date Bought\",\"Date Sold\"\n",file);
while(*position->ticker!='\0') {
fprintf(file,"%s,%d,%d\n",
position->ticker,
position->date_bought,
position->date_sold);
position++;
}

fclose(file);

return 1;
}

-------------
portfolio_m.c
-------------
#include <stdio.h>
#include <stdlib.h>

#include "portfolios.h"

int main(void) {
t_portfolio *portfolio=NULL;
char *portfolio_filepath="portfolio.txt";
char *new_portfolio_filepath="new_portfolio.txt";

printf("Hello Portfolio World!!!\n");

if((portfolio=read_portfolio(portfolio_filepath))==NULL) {
printf("\nFailed to read portfolio\n");
goto Buh_Bye;
}

view_portfolio(portfolio);

if(!save_portfolio(portfolio,new_portfolio_filepath))
printf("\nFailed to save portfolio\n");

free_portfolio(portfolio);

Buh_Bye :

return 0;
}

---
William Ernest Reid


Richard Heathfield

unread,
Jul 8, 2008, 3:34:26 AM7/8/08
to
Bill Reid said:

>
> Bill Reid <horme...@happyhealthy.net> wrote in message
> news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...
>
> DAMN!!! I hate it when that happens!!!

It would happen less if you listened more.

There are plenty of bright people in here.

You can always tell the bright ones, because they are the ones who learn
from other people's crits.

And then there are those who, like Bill, take criticism as insult and
respond to it with invective.

Not so bright.

Okay, Bill, flame away. Shouting is what you're good at, so you get on with
your shouting and let the poor newbie get on with learning C from people
who know it.

jacob navia

unread,
Jul 8, 2008, 3:36:46 AM7/8/08
to
Richard Heathfield wrote:
> Bill Reid said:
>
>> Bill Reid <horme...@happyhealthy.net> wrote in message
>> news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...
>>
>> DAMN!!! I hate it when that happens!!!
>
> It would happen less if you listened more.
>
> There are plenty of bright people in here.
>
> You can always tell the bright ones, because they are the ones who learn
> from other people's crits.
>
> And then there are those who, like Bill, take criticism as insult and
> respond to it with invective.
>
> Not so bright.
>
> Okay, Bill, flame away. Shouting is what you're good at, so you get on with
> your shouting and let the poor newbie get on with learning C from people
> who know it.
>

Yes, for instance mr heathfield that can't figure out that pointers
aren't always 32 bits...

See "C unleashed"

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32

Ron Ford

unread,
Jul 8, 2008, 3:56:24 AM7/8/08
to
On Tue, 08 Jul 2008 09:36:46 +0200, jacob navia posted:

> Richard Heathfield wrote:
>> Bill Reid said:
>>
>>> Bill Reid <horme...@happyhealthy.net> wrote in message
>>> news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...
>>>
>>> DAMN!!! I hate it when that happens!!!
>>
>> It would happen less if you listened more.
>>
>> There are plenty of bright people in here.
>>
>> You can always tell the bright ones, because they are the ones who learn
>> from other people's crits.
>>
>> And then there are those who, like Bill, take criticism as insult and
>> respond to it with invective.
>>
>> Not so bright.
>>
>> Okay, Bill, flame away. Shouting is what you're good at, so you get on with
>> your shouting and let the poor newbie get on with learning C from people
>> who know it.
>>
>
> Yes, for instance mr heathfield that can't figure out that pointers
> aren't always 32 bits...
>
> See "C unleashed"

I couldn't find the guarantee of 32-bit pointers. I don't think it's any
big secret that there were a lot of errors. My favorite of the whoppers is
Jack Klein's visualization of an error-correcting Hamming code announced as
(12,4) instead of (12,8), which completely reverses the role of the parity
and data bits.
--
I hate all sports as rabidly as a person who likes sports hates common
sense.
H. L. Mencken

Richard Heathfield

unread,
Jul 8, 2008, 4:29:30 AM7/8/08
to
Ron Ford said:

> On Tue, 08 Jul 2008 09:36:46 +0200, jacob navia posted:

<snip>


>>
>> Yes, for instance mr heathfield that can't figure out that pointers
>> aren't always 32 bits...

(Mr Heathfield's first encounter with C pointers was in MS-DOS, in which
pointers are 20 bits, and there are various 16- and 32-bit bodges
available to deal with this weirdity - and Mr Heathfield has also worked
on systems with other pointer sizes, so Mr Heathfield is well aware that
pointer size is not written in stone. Perhaps Mr Navia would be so kind as
to point out where CU claims that pointers are always 32 bits?)

>>
>> See "C unleashed"

Which bit?

> I couldn't find the guarantee of 32-bit pointers. I don't think it's any
> big secret that there were a lot of errors.

No, it's no secret. We've documented as many as we can find. It would be
nice to have the chance to go back and have another crack at it, fix all
this stuff, but unfortunately that isn't going to happen, but we've done
what we can.

This is an illustration of my earlier point - that the bright response to
bug reports is to investigate the reports and, in cases where the reports
are correct, to put them right if possible, or at least to record them,
publish them, and learn from them. NOT to yell at the guy who made the
crit. There are several people in comp.lang.c who have yet to learn this.

<snip>

jacob navia

unread,
Jul 8, 2008, 4:32:27 AM7/8/08
to
Richard Heathfield wrote:

Perhaps Mr Navia would be so kind as
> to point out where CU claims that pointers are always 32 bits?)

Specifically in Chapter 11, page 353 you assume
sizeof pointer is equal to sizeof int...

It will work when sizeof pointer is equal to sizeof int
(windows or linux 32 bit versions) but will crash when
sizeof int != sizeof pointer (windows 64 bits.

I would never mind that you have a bug. What bothers me
is how you make fun of other people when they try to
write something and have a bug!

This slightly ironic tone, this "dettached" viewpoint,
as you never make those kind of errors.

Richard Heathfield

unread,
Jul 8, 2008, 5:12:12 AM7/8/08
to
jacob navia said:

> Richard Heathfield wrote:
>
> Perhaps Mr Navia would be so kind as
>> to point out where CU claims that pointers are always 32 bits?)
>
> Specifically in Chapter 11, page 353 you assume
> sizeof pointer is equal to sizeof int...

I don't see it. I *do* see where I assume that sizeof(int **) is equivalent
to sizeof(int *), which is itself a bug - one that was first reported (by
Chris Mears) and published (almost) EIGHT YEARS AGO - but a far cry from
assuming that pointers are always 32 bits. I can't see the number 32
anywhere on that page.

I think the simplest explanation of your claim is that you have made two
errors here: 1) you have assumed that ints are always 32 bits; 2) you have
misread my code as if it assumed that sizeof pointer is equal to sizeof
int. Given those errors, it is easy to see why you might think I'd claimed
pointers are 32 bits. But those are your mistakes, not mine.

You made an incorrect claim, or at least a claim that you have not
substantiated - that CU claims pointers are always 32 bits. Your attempted
substantiation, Ch 11 p353, modified the claim itself, and the modified
claim was also incorrect. And the bug that /is/ there was documented on
the errata page in November 2000.


> It will work when sizeof pointer is equal to sizeof int
> (windows or linux 32 bit versions) but will crash when
> sizeof int != sizeof pointer (windows 64 bits.
>
> I would never mind that you have a bug. What bothers me
> is how you make fun of other people when they try to
> write something and have a bug!

I don't make fun of people for making mistakes. I do sometimes make fun of
people for refusing to learn from them.

> This slightly ironic tone, this "dettached" viewpoint,

I save the ironic tone for special occasions, which are fewer than they
used to be, now that the Terrible Triplets are safely behind plonkbars.
The detached viewpoint is one that you would do well to cultivate. It
might well bring your blood pressure down.

> as you never make those kind of errors.

Everybody makes mistakes. The question is not whether we are perfect, but
whether we are striving to become perfect. Those who are trying to become
better programmers will react to criticisms of their code in a positive
way.

jacob navia

unread,
Jul 8, 2008, 5:18:22 AM7/8/08
to
Richard Heathfield wrote:
> jacob navia said:
>
>> Richard Heathfield wrote:
>>
>> Perhaps Mr Navia would be so kind as
>>> to point out where CU claims that pointers are always 32 bits?)
>> Specifically in Chapter 11, page 353 you assume
>> sizeof pointer is equal to sizeof int...
>
[snip]

And the bug that /is/ there was documented on
> the errata page in November 2000.
>
>
Right.

So please stop making fun of people when they have a bug.

And here in this same group I have pointed several bugs in code
you posted, so just be kind with others when they have a bug.

Richard Heathfield

unread,
Jul 8, 2008, 5:39:59 AM7/8/08
to
jacob navia said:

> Richard Heathfield wrote:
>> jacob navia said:
>>
>>> Richard Heathfield wrote:
>>>
>>> Perhaps Mr Navia would be so kind as
>>>> to point out where CU claims that pointers are always 32 bits?)
>>> Specifically in Chapter 11, page 353 you assume
>>> sizeof pointer is equal to sizeof int...
>>
> [snip]
> And the bug that /is/ there was documented on
>> the errata page in November 2000.
>>
>>
> Right.

That's called selective quotation, and it's considered dishonest. You have
snipped out all the stuff where I tore your claim apart, and made it
appear (above) as if we were in agreement, whereas in fact you made a
false claim which I debunked.

>
> So please stop making fun of people when they have a bug.

Please stop beating your wife. /* This request, like yours, is based on a
false assumption. */

> And here in this same group I have pointed several bugs in code
> you posted,

If that's true, you will have no trouble proving it. If it's false, you
will find an excuse not to try to prove it. I'm not a betting man but, if
I were, I would bet on the latter.

And even if it *is* true (which I doubt), it's of no consequence. People in
comp.lang.c make mistakes all the time, and corrections are the order of
the day. It would be silly to measure people by the number of mistakes
they make. What matters is whether they can learn from them.

A newbie posts some code, and some reg or other posts a crit. The world
holds its breath! Will the newbie respond with anger and resentment and
denial and aggression, like a Navia or a Reid? Or will he accept the
criticism and use it to improve his code, like a Thompson or a Tobin?


> so just be kind with others when they have a bug.

Please stop drinking to excess. /* This request, like yours, is based on a
false assumption. */

Keith Thompson

unread,
Jul 8, 2008, 11:41:53 AM7/8/08
to
jacob navia <ja...@nospam.com> writes:
> Richard Heathfield wrote:
>
> Perhaps Mr Navia would be so kind as
>> to point out where CU claims that pointers are always 32 bits?)
>
> Specifically in Chapter 11, page 353 you assume
> sizeof pointer is equal to sizeof int...
>
> It will work when sizeof pointer is equal to sizeof int
> (windows or linux 32 bit versions) but will crash when
> sizeof int != sizeof pointer (windows 64 bits.
>
> I would never mind that you have a bug. What bothers me
> is how you make fun of other people when they try to
> write something and have a bug!
>
> This slightly ironic tone, this "dettached" viewpoint,
> as you never make those kind of errors.

I would never mind that *you* have a bug. What bothers me is when you
treat bug reports as personal attacks. I have never seen Richard do
this; I see you do it over and over again.

And you don't seem to understand the difference.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Cromulent

unread,
Jul 8, 2008, 6:26:47 PM7/8/08
to
On 2008-07-07 23:52:53 +0100, "Bill Reid" <horme...@happyhealthy.net> said:

> <snip - a very useful post>

Thank you for that, it was incredibly useful. I'll have to spend a
little time digesting that tomorrow evening, I didn't expect anything
of that magnitude.

Also thanks for the other pointers in this thread, I'll get the hang of
this some day :).

Bill Reid

unread,
Jul 8, 2008, 7:34:49 PM7/8/08
to

Richard Heathfield <r...@see.sig.invalid> wrote in message
news:B5adndqbnc70iu7V...@bt.com...

> > Bill Reid <horme...@happyhealthy.net> wrote in message
> > news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...
> >
> > DAMN!!! I hate it when that happens!!!
>
> It would happen less if you listened more.

????

I wouldn't make mistakes if I "listened more"? Really good
"listeners" rarely or never make mistakes?

If that's your "logic", I don't agree, and have to conclude that
"troll zero" is getting ever-more irrational in his dotage...

> There are plenty of bright people in here.
>
> You can always tell the bright ones, because they are the ones who learn
> from other people's crits.
>
> And then there are those who, like Bill, take criticism as insult and
> respond to it with invective.
>
> Not so bright.
>
> Okay, Bill, flame away. Shouting is what you're good at, so you get on
with
> your shouting and let the poor newbie get on with learning C from people
> who know it.

You know, right in the code I "corrected" there was ANOTHER
error. DOUBLE-DAMN!!!

But instead of pointing out any of the several actual errors in what
I posted in a legitimate and knowledgeable attempt to help the guy,
you chose to merely indulge in content-less and misleading personal
attacks.

Which is why you'll always be "troll zero" 'round these parts...

---
William Ernest Reid

Richard Heathfield

unread,
Jul 8, 2008, 7:51:43 PM7/8/08
to
Bill Reid said:

>
> Richard Heathfield <r...@see.sig.invalid> wrote in message
> news:B5adndqbnc70iu7V...@bt.com...
>> > Bill Reid <horme...@happyhealthy.net> wrote in message
>> > news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...
>> >
>> > DAMN!!! I hate it when that happens!!!
>>
>> It would happen less if you listened more.
>
> ????
>
> I wouldn't make mistakes if I "listened more"?

No, that's not what I said. I said you'd make *fewer* mistakes if you
listened more.

> Really good "listeners" rarely or never make mistakes?

That's not what I said either.

> If that's your "logic", I don't agree,

And if Keith Thompson's computer is a bicycle, I play the violin. So what?

> But instead of pointing out any of the several actual errors in what
> I posted

I've done that several times before, and just got yelled at for my pains.
So have several other people here who've tried to help you. If only you'd
listened more to these folks, you'd have made fewer mistakes.

If you want me to help you out by pointing out your mistakes, you need to
convince me that it has become worthwhile to help you - that you are
capable of learning from such help, and able to receive it in a civilised
manner. And if you want to convince me of that, you're not making your
task any easier by hurling abuse.

Bill Reid

unread,
Jul 8, 2008, 9:31:12 PM7/8/08
to

Richard Heathfield <r...@see.sig.invalid> wrote in message
news:5_ednbNXD43qYe7V...@bt.com...

> Bill Reid said:
> > Richard Heathfield <r...@see.sig.invalid> wrote in message
> > news:B5adndqbnc70iu7V...@bt.com...
> >> > Bill Reid <horme...@happyhealthy.net> wrote in message
> >> > news:97xck.102849$102....@bgtnsc05-news.ops.worldnet.att.net...
> >> >
> >> > DAMN!!! I hate it when that happens!!!
> >>
> >> It would happen less if you listened more.
> >
> > ????
> >
> > I wouldn't make mistakes if I "listened more"?
>
> No, that's not what I said. I said you'd make *fewer* mistakes if you
> listened more.

OK, logically you're just making a distinction between the
"reducto ad absurdum" and the fact that your assertion is
merely absurd: irrational, unprovable, and totally unsupported
by evidence...

> > Really good "listeners" rarely or never make mistakes?
>
> That's not what I said either.

OK, in this case you are disclaiming a logical conclusion that
doesn't rely totally on the "reducto", but IS a fully "truth-positive"
conclusion based on your absurd assertion, and so you are
probably disingenuously attempting to disclaim any rationatination
of your absurdity based only on the juvenile defense of precise
wording.

> > If that's your "logic", I don't agree,
>
> And if Keith Thompson's computer is a bicycle, I play the violin. So what?

Exactly. You made an absurd statement, which can't sustain
even the slightest logical scrutiny. Your ACTUAL position is that
since you are angry, I make mistakes. Of course, the number
of mistakes I make has little to nothing to do with your anger.

I WOULD accept the assertion that the number of mistakes you
POINT OUT is directly related to YOUR anger, which probably is
the result of some over-arching life frustation. Perhaps this is what
you REALLY meant to say...or what you could never admit...

> > But instead of pointing out any of the several actual errors in what
> > I posted
>
> I've done that several times before, and just got yelled at for my pains.

I don't remember anybody ever mistreating you for pointing out a
true mistake, and I certainly never have...

> So have several other people here who've tried to help you. If only you'd
> listened more to these folks, you'd have made fewer mistakes.

Ridiculous. Of course, now you've slipped right into drawing conclusions
based on your absurd unsupported assertion, but when I do the same, you
hypocritically disclaim it by saying, "that's not what I said."

But you can't wiggle out of the above idiotic statement using that
piece of juvenile argumentation. My mistake was using the wrong
format specifier for scanf(), and I would have made it inadvertantly
regardless of any "corrections" I did not "listen to" enough in the
past. I also misssspeel words inadvertantly, lose my car keys
(or I used to, now I've got a "system"), forget people's birthdays,
and make any number of other totally human errors, and NONE
of them has ANYTHING to do with the amount of "listening" I do.

> If you want me to help you out by pointing out your mistakes, you need to
> convince me that it has become worthwhile to help you - that you are
> capable of learning from such help, and able to receive it in a civilised
> manner.

Has anybody told you lately that you're a pompous jerk? Oh, yeah,
about 10 people just today...

Look, if you weren't SUCH a pompous jerk, you'd correct my mistakes
in the same way I corrected my own mistake, and for the same reason: to
genuinely try to avoid confusion. But as a die-hard pompous jerk, you
are too lazy or stupid to correct actual errors, and instead resort to
childish insults in between bouts of useless pedantry, and then
amazingly enough, seem to actually believe that I DESIRE your
input on ANYTHING.

> And if you want to convince me of that, you're not making your
> task any easier by hurling abuse.

I don't want to convince you of ANYTHING...as with all trolls, my only
hope is that you'll just tire of your trollery here and go away, but I
daren't
raise my "hope" to the level of a "goal" because I know it would be
Quioxtically impossible to attain...

---
William Ernest Reid

Ron Ford

unread,
Jul 8, 2008, 10:06:04 PM7/8/08
to
On Tue, 08 Jul 2008 09:12:12 +0000, Richard Heathfield posted:

> jacob navia said:
>
>> Richard Heathfield wrote:
>>
>> Perhaps Mr Navia would be so kind as
>>> to point out where CU claims that pointers are always 32 bits?)
>>
>> Specifically in Chapter 11, page 353 you assume
>> sizeof pointer is equal to sizeof int...
>
> I don't see it. I *do* see where I assume that sizeof(int **) is equivalent
> to sizeof(int *), which is itself a bug - one that was first reported (by
> Chris Mears) and published (almost) EIGHT YEARS AGO - but a far cry from
> assuming that pointers are always 32 bits. I can't see the number 32
> anywhere on that page.

I don't see it quite like you say it. You give three different methods for
resizing arrays. All three look significantly different. Is it one of
those assumptions that fouls the whole thing?

One other thing, I was poking around n1256.pdf to find out what guarantees
there are on the width of an int. I found:

A ‘‘plain’’ int object has the natural size suggested by the
architecture of the execution environment (large enough to contain any
value in the range
INT_MIN to INT_MAX as defined in the header <limits.h>).

and

—minimum value for an object of type int
INT_MIN -32767 // -(2 15
- 1)
—maximum value for an object of type int
INT_MAX +32767 // 2 15
- 1

Are there circumstances in which a C int object is 47 bits?
--
The only really happy folk are married women and single men.
H. L. Mencken

user923005

unread,
Jul 8, 2008, 11:33:10 PM7/8/08
to
On Jul 8, 1:32 am, jacob navia <ja...@nospam.com> wrote:
> Richard Heathfield wrote:
>
> Perhaps Mr Navia would be so kind as
>
> > to point out where CU claims that pointers are always 32 bits?)
>
> Specifically in Chapter 11, page 353 you assume
> sizeof pointer is equal to sizeof int...

I have the book open there to that page and cannot find that
assumption either implicitly or explicitly. Could you be so kind as
to point it out exactly? I am not doubting the existance, I am only
unable to locate it.

> It will work when sizeof pointer is equal to sizeof int
>   (windows or linux 32 bit versions) but will crash when
>   sizeof int != sizeof pointer (windows 64 bits.
>
> I would never mind that you have a bug. What bothers me
> is how you make fun of other people when they try to
> write something and have a bug!

Are you suggesting that you do not make fun of (or otherwise deride)
other people who post here?

> This slightly ironic tone, this "dettached" viewpoint,
> as you never make those kind of errors.

Richard is remarkably mistake free, as far as I can tell. Maybe
Lawrence Kirby, Dan Pop or Tanmoy Bhattacharya produce less defects
per post on average but I guess Richard is in the top 0.1% of c.l.c
posters as far as correctness is concerned. That having been said, I
have found that Richard is also remarkably forthright about admitting
to a mistake on the rare occasions when it does occur.

According to:
http://www.informit.com/articles/article.aspx?p=369222&seqNum=9
"A typical software development project injects approximately 100–250
defects per thousand lines of code [Humphrey 02]."

Not a very comforting thought. Hence the drive for correctness common
to news:comp.lang.c should be viewed as laudable (IMO-YMMV)


user923005

unread,
Jul 8, 2008, 11:40:19 PM7/8/08
to
On Jul 8, 2:18 am, jacob navia <ja...@nospam.com> wrote:
> Richard Heathfield wrote:
> > jacob navia said:
>
> >> Richard Heathfield wrote:
>
> >> Perhaps Mr Navia would be so kind as
> >>> to point out where CU claims that pointers are always 32 bits?)
> >> Specifically in Chapter 11, page 353 you assume
> >> sizeof pointer is equal to sizeof int...
>
> [snip]
>   And the bug that /is/ there was documented on> the errata page in November 2000.
>
> Right.
>
> So please stop making fun of people when they have a bug.
>
> And here in this same group I have pointed several bugs in code
> you posted, so just be kind with others when they have a bug.

Even Donald Knuth makes mistakes. If Donald Knuth can make a mistake,
then everyone can (and will) make them.

You do have a valuable suggestion here (paraphrasing from "Bill and
Ted's Excellent Adventure"):
Bill: "Be excellent to each other."

Truthfully, if we could all have the sensitivity of Tanmoy B., then
news:comp.lang.c would be a better place.

On the other hand, having some sort of lurid blood in my veins, I will
admit that I thoroughly enjoyed seeing Dan Pop fry recalcitrant
posters from time to time. I'm working on that.

Richard Heathfield

unread,
Jul 9, 2008, 1:08:46 AM7/9/08
to
Bill Reid said:

> Richard Heathfield <r...@see.sig.invalid> wrote in message

> news:5_ednbNXD43qYe7V...@bt.com...
>> Bill Reid said:
<snip>


>> >
>> > I wouldn't make mistakes if I "listened more"?
>>
>> No, that's not what I said. I said you'd make *fewer* mistakes if you
>> listened more.
>
> OK, logically you're just making a distinction between the
> "reducto ad absurdum" and the fact that your assertion is
> merely absurd:

No, I was just trying to show you how you could make fewer mistakes. How
stupid of me to even consider trying to help you.

<lots of nonsense snipped>

Richard Heathfield

unread,
Jul 9, 2008, 1:15:49 AM7/9/08
to
Ron Ford said:

> On Tue, 08 Jul 2008 09:12:12 +0000, Richard Heathfield posted:
>
>> jacob navia said:
>>
>>> Richard Heathfield wrote:
>>>
>>> Perhaps Mr Navia would be so kind as
>>>> to point out where CU claims that pointers are always 32 bits?)
>>>
>>> Specifically in Chapter 11, page 353 you assume
>>> sizeof pointer is equal to sizeof int...
>>
>> I don't see it. I *do* see where I assume that sizeof(int **) is
>> equivalent to sizeof(int *), which is itself a bug - one that was first
>> reported (by Chris Mears) and published (almost) EIGHT YEARS AGO - but a
>> far cry from assuming that pointers are always 32 bits. I can't see the
>> number 32 anywhere on that page.
>
> I don't see it quite like you say it. You give three different methods
> for
> resizing arrays.

For providing resizeable two-dimensional arrays.

> All three look significantly different. Is it one of
> those assumptions that fouls the whole thing?

The assumption that T* and T** have the same width is not a good one. It
affects only the second method of the three. (To save you looking for it,
I don't actually show source for the first method.) The failing is with
the code on pp353-356top. In practice, it'll work fine, because in
practice, T* normally does have the same size and alignment requirements
as T** - but in theory there could exist a platform on which it would
fail.

> One other thing, I was poking around n1256.pdf to find out what
> guarantees
> there are on the width of an int.

It's at least 16 bits wide, but can be wider.

<snip>



> Are there circumstances in which a C int object is 47 bits?

The rules don't forbid it.

Antoninus Twink

unread,
Jul 9, 2008, 1:37:46 PM7/9/08
to
On 8 Jul 2008 at 23:51, Richard Heathfield wrote:
> If you want me to help you out by pointing out your mistakes, you need to
> convince me that it has become worthwhile to help you - that you are
> capable of learning from such help, and able to receive it in a civilised
> manner. And if you want to convince me of that, you're not making your
> task any easier by hurling abuse.

It's abundantly clear from this one paragraph that there's absolutely no
danger of Bill losing out on any "help" from you - but if he's lucky you
might killfile him and then he'll miss out on a load of patronizing
garbage dispensed from on high.

Kenny McCormack

unread,
Jul 9, 2008, 4:50:47 PM7/9/08
to
In article <slrng79tra...@nospam.invalid>,

Patronizing garbage is as good as it gets around here.

You oughta know that by now.

0 new messages