Warning to newbies

S

Squeamizh

A couple of points:

1.  I'm not all *that* strongly autistic, but enough that I don't really
care whether people are "attacking" me or not.
2.  I have Nilges plonked.
3.  Even when I didn't have him plonked, I'd realized after about two tries
at communicating with him that he was hilarious.  I went out of my way to
wave the autism thing at him to get him to spend weeks trying to insult me
with it, and the decision to mention the lack of a CS degree was made with
full awareness that he'd obsess on it for months.
4.  If behavior is sufficiently predictable, and sufficiently stupid, it is
not meaningfully an attack.

Basically, if your mom's a drill sergeant, and another kid finds out that
your mom has combat boots, the ensuing cries of "Your mommy wears combat
boots!" are not a particularly emotionally significant thing.  :)

You're an idiot with regard to the social side of things. You're
pretty good on c-related stuff, perhaps a genius. Anyway, stop posting
about social shit.
 
K

Keith Thompson

Squeamizh said:
You're an idiot with regard to the social side of things. You're
pretty good on c-related stuff, perhaps a genius. Anyway, stop posting
about social shit.

Was this meant to demonstrate that you're better at "the social side
of things" than he is?
 
B

blmblm

forgot an example! Games. The "physics" is always a compromise between
accuracy and runability and they have to aim the game at what they
*think* the typical hardware will be when they finish writing the
game!

[stuff on scalability]
Interesting comments. Thank you. OK, it sounds like software will be
in ten years something that only highly qualified postdocs will write
anew,

maybe clever libraries or frameworks will help?

I'm inclined to think that they might. I'm also inclined to think
that people who start out programming for multiple processors/cores
may find it more natural, and easier, than people whose early
training was all with one-thing-at-a-time programs. Purely my
opinion, though -- I have no evidence one way or another!

[ snip ]

And the ones inside the field seem to mainly know him as the inventor
of a particular graph algorithm. :-(

Interesting guy, as best I can tell, and/but a bit eccentric.
Aren't a lot of the EWD "notes" (informal publications) hand-written?
and I seem to remember that in one co-authored book [*] he seemed
to be not only telling mathematicians how to write proofs but also
English teachers how to punctuate.

[*] authors Dijkstra and Scholten, and I'm not remembering the
title for sure, but based on a quick Web search I think it may be
"Predicate Calculus and Program Semantics". Very interesting,
and relevant to the discussion on formal proofs of correctness.

[ snip ]
 
S

Seebs

Squeamizh wrote (in reply to Seebs):
I can think of plenty of worse idiots on the social side of things, and
quite a few of them subscribe to this newsgroup.

Oddly, people seem sort of split on whether I'm utterly inept socially
or fairly brilliant. This is probably because my social skills are
wildly erratic (as are most of my other skills).

More interestingly, there's a strong tendency for me to find easy things
comparatively difficult, and difficult things comparatively easy. So, for
instance, I might have a very hard time determining whether or not someone
is "smiling" (this sounds easy until you realize that, for instance, grimaces
are not a kind of smile), which nearly any two-year-old can do instantly
and quite reliably. On the other hand, I can listen to people talk for a
while and tell them things about their internal state that they had been
trying to figure out for years. Sometimes.
I have to agree with you there, although he is by no means infallible.

Certainly not! I currently hold a record at $DAYJOB for the largest number
of P1 (blocking multiple people from getting anything done) bugs introduced
while fixing a P3 (nuisance with workaround) bug. Although technically,
most of that was shell scripts, not C.

Anyway, I'll post about whatever interests me. Social stuff is rarely
topical here, but every so often it becomes interesting or relevant. A
little topic drift never hurt anyone. (Note the distinction between
topic drift and threads which started out off topic.)

-s
 
B

blmblm

[ snip ]
I'll contribute one.

[ snip ]
for (i = 0; new_environs.name; ++i) {


I notice that you use "++i" where I think the majority of C
programmers would write "i++". What's your rationale for doing so?
I prefer ++i myself, but my reasons for doing so seem a bit flimsy,
and I wonder whether I should just follow the majority ....

[ snip ]
 
B

blmblm

Can't you just let Moore's Law handle "efficiency"?
interesting question.
FWIW: You can't.
First off, Moore's Law doesn't expand as fast as some particularly
expensive operations do. Secondly, even if it does expand with the right
big-O relation, it may not expand fast enough to do much good.

[...] your comment is nonsense, and I don't think you
understand computational complexity, for if "it" expands with "the
right big O relation", then it follows that this is fast
enough...

what's the "right" big O notation?
although in fact, we shouldn't rely on Moore's Law to justify
the use of mathematically slow algorithms, and that was not implied by
the original post. We weren't discussing buying faster computers so as
to code bubble sort, we were discussing running effective algorithms
faster.

not all problems have a known "good" (polynomial) algorithm. Think NP
complete (travelling salesman etc.). I gave you a bunch of examples in

Traveling salesman has a "good" algorithm. It's called simulated
annealling.

Which gives an approximate solution, no? because the existence of
a polynomial-time algorithm for the TSP as stated in discussions of
computational complexity and NP-completeness form would be big news.
I worked at Motorola in 1979. Years later, a Siemens engineer told me
that the reason Motorola didn't have a marketable cellphone in 1975
was that under Nixon, the FCC was to embroiled in politics as a
consequence of Vietnam and Watergate that it would not release
frequencies needed to implement cellphones.

[ snip ]
 
S

spinoza1111

I'm not talking about the ugly corporate phrase and concept "social
skills". In "Politics and the English Language", George Orwell writes
"Never use a metaphor, simile, or other figure of speech which you are
used to seeing in print.". He was thinking about the mindless Left use
of unanalyzed phrases such as "bourgeois morality".

Today, it's more common to use corporate phrases such as "social
skills".

This phrase implies in fact that instead of common decency (the Golden
Rule) one can instead cultivate "social skills", where "skills" imply
the ability to manipulate others, for example into hiring you as a
programmer without any university preparation, and then not making you
write code.

You know what the "golden rule" is, don't you, Peter? Do unto others
as you would have done unto you?

How would YOU like it if someone had posted a superficial criticism of
your work after refusing to work with you at McGraw Hill or Apress,
filled with its own errors while caricaturing you as the source of all
error and making a crude and foul imprecation out of your father's
name?

While posting code here with bugs (% not followed by s) while
expecting to be forgiven? While expecting tolerance for having a
fashionable disease and a fashionable sexual orientation, while using
forms of language ("moron") characteristic of bullies and fag bashers?



Oddly, people seem sort of split on whether I'm utterly inept socially
or fairly brilliant.  This is probably because my social skills are
wildly erratic (as are most of my other skills).

But you couldn't have the decency to write "Herb, despite his errors,
is a great teacher of C, to the extent that even his errors educate
the student". This is what people thought of Albert Einstein, whose
limitations in mathematics were well-known (Walter Kaufman's 2007
biography makes this clear) and which caused him to be unable in
Princeton to come up with an alternative to quantum mechanics.

You want it to be said of you that "Peter is a charming and sweet and
brilliant guy who overcame his disease and sexual orientation with
courage". But if you coin an ugly phrase, "Bullschildt", about a
colleague, and you call a fellow Apress author a moron, we aren't
gonna say this about you.
 
S

spinoza1111

forgot an example! Games. The "physics" is always a compromise between
accuracy and runability and they have to aim the game at what they
*think* the typical hardware will be when they finish writing the
game!
[stuff on scalability]
Interesting comments. Thank you. OK, it sounds like software will be
in ten years something that only highly qualified postdocs will write
anew,
maybe clever libraries or frameworks will help?

I'm inclined to think that they might.  I'm also inclined to think
that people who start out programming for multiple processors/cores
may find it more natural, and easier, than people whose early
training was all with one-thing-at-a-time programs.  Purely my
opinion, though -- I have no evidence one way or another!

[ snip ]

And the ones inside the field seem to mainly know him as the inventor
of a particular graph algorithm.  :-(

Interesting guy, as best I can tell, and/but a bit eccentric.

God, I hate that word, "eccentric". Its use normalizes deviance.
Aren't a lot of the EWD "notes" (informal publications) hand-written?  

In later life he wrote his notes by hand.
and I seem to remember that in one co-authored book [*] he seemed
to be not only telling mathematicians how to write proofs but also
English teachers how to punctuate.  

He felt himself better educated than most of his colleagues, with some
justice.
[*] authors Dijkstra and Scholten, and I'm not remembering the
title for sure, but based on a quick Web search I think it may be
"Predicate Calculus and Program Semantics".  Very interesting,
and relevant to the discussion on formal proofs of correctness.

[ snip ]
 
S

spinoza1111

spinoza1111wrote:
I know of no Usenet convention to that effect.

Me neither.

And I've been doing this since before the Great Renaming.
I'd add an ObC, only I can't think of one.

I'll contribute one.

I recently wanted to write something which would derive a string value,
then substitute it into another string.  Actually, into several other strings.

The problem is that it might be substituted several times, so I couldn't
just do something like:

        char *replace = "replace_here:%s";

and use sprintf.

(In this particular case, the values are "environment variables", but that's
a detail of no particular relevance to C.)

My solution, which is a bit hacky, but I sorta liked:

struct { char *name, *template; } new_environs[] = {
  { "PERL5LIB", "%s/lib64/perl5/5.10.0/i686-linux:%s/lib64/perl5/5.10.0:%s/lib64/perl5/site _perl/5.10.0/i686-linux:%s/lib64/perl5/site_perl/5.10.0:%s/lib64/perl5/vend or_perl/5.10.0/i686-linux:%s/lib64/perl5/vendor_perl/5.10.0:%s/lib64/perl5/ vendor_perl:." },
  { "LD_LIBRARY_PATH", "%s/lib64:%s/lib:%s/lib64" },
  { 0, 0 }

};

Then, down below:

        for (i = 0; new_environs.name; ++i) {
          char *new_environ;
          char *t;
          char *u;    
          size_t len = strlen(new_environs.template) + 5;
          for (s = new_environs.template; t = strchr(s, '%'); s = t + 1) {
            len += strlen(parent_path);
          }
          new_environ = malloc(len);
          u = new_environ;
          *u = '\0';
          for (s = new_environs.template; t = strchr(s, '%'); s = t + 2) {
            u += snprintf(u, (len - (u - new_environ)), "%.*s%s",
                          t - s, s, parent_path);
          }
          snprintf(u, (len - (u - new_environ)), "%s", s);
          setenv(new_environs.name, new_environ, 1);
          free(new_environ);
        }

The "setenv" function is a Unixism, which, given a name and a value, makes
that name/value pair available to future execution.

The calculations are very careless; my goal was not to calculate exactly
the right length, but rather, to calculate a length which could be easily
shown to be definitively long enough.

I am, however, pretty happy with this part:

          for (s = new_environs.template; t = strchr(s, '%'); s = t + 2) {
            u += snprintf(u, (len - (u - new_environ)), "%.*s%s",
                          t - s, s, parent_path);
          }

Note that I don't check, in this version, whether it's "%s" or some other
character after a %.  This was one of those "we need something within half
an hour that will work for this circumstance, we can clean it up tomorrow"
jobs.

-s
p.s.:  Side note for Unix users:  Yes, it's okay to free the argument to
setenv after passing it in, unlike putenv().


Gee, Peter, what does this prove?

You can write a trivial piece of code?

But it has a bug, as you yourself point out. Why should you not be
exposed to the same scorn you showed Herb?

The code looks incorrectly for %s in two places, so the bug is doubled
in its effect.

Oh yes, and you don't check malloc for failure.

The SAME sort of nits exist in this code as exist in Herb. Are we to
forgive you? Sure, you needed the first draft in a half hour, but you
could have posted a cleaned up version.

But, then you would have found that your basic approach looks for %s
in two different places. It's gonna get nasty when you get around to
it.

Actually checking for %s and not % means that you should have done
things in one pass, not a pass to determine the malloc request and a
pass to create the output string. Instead, you needed to create a
linked list of output string segments whilst calculating the size of
the final malloc. This way the second pass would have reduced to just
tying the segments together without repeating the strchr searches for
% (and the extra checks for a following s).

Alternatively, you could have malloc'd for the worst case and done
everything in one pass. This would have been imagining that the input
string consisted of nothing but %s sequences, and mallocing its length
halved times the substitute string length plus one for Nul, then
freeing all the storage you don't need.

Even better, you would have written the code as a replace function
handling anything, using a linked list or worst case malloc which
assumes that the input string is a series of the strings to be
replaced.

Even better, you would have replaced ALL string handling by something
that actually works, emulating the best C programmers, who always find
themselves trying to exit the Truman Show that is C by using C to
create something else.
 
S

spinoza1111

Me neither.
And I've been doing this since before the Great Renaming.
I'll contribute one.
I recently wanted to write something which would derive a string value,
then substitute it into another string.  Actually, into several other strings.
The problem is that it might be substituted several times, so I couldn't
just do something like:
        char *replace = "replace_here:%s";
and use sprintf.
(In this particular case, the values are "environment variables", but that's
a detail of no particular relevance to C.)
My solution, which is a bit hacky, but I sorta liked:
struct { char *name, *template; } new_environs[] = {
  { "PERL5LIB", "%s/lib64/perl5/5.10.0/i686-linux:%s/lib64/perl5/5.10..0:%s/lib64/perl5/site _perl/5.10.0/i686-linux:%s/lib64/perl5/site_perl/5.10.0:%s/lib64/perl5/vend or_perl/5.10.0/i686-linux:%s/lib64/perl5/vendor_perl/5.10.0:%s/lib64/perl5/ vendor_perl:." },
  { "LD_LIBRARY_PATH", "%s/lib64:%s/lib:%s/lib64" },
  { 0, 0 }

Then, down below:
        for (i = 0; new_environs.name; ++i) {
          char *new_environ;
          char *t;
          char *u;    
          size_t len = strlen(new_environs.template) + 5;
          for (s = new_environs.template; t = strchr(s, '%'); s = t + 1) {
            len += strlen(parent_path);
          }
          new_environ = malloc(len);
          u = new_environ;
          *u = '\0';
          for (s = new_environs.template; t = strchr(s, '%'); s = t + 2) {
            u += snprintf(u, (len - (u - new_environ)), "%.*s%s",
                          t - s, s, parent_path);
          }
          snprintf(u, (len - (u - new_environ)), "%s", s);
          setenv(new_environs.name, new_environ, 1);
          free(new_environ);
        }

The "setenv" function is a Unixism, which, given a name and a value, makes
that name/value pair available to future execution.
The calculations are very careless; my goal was not to calculate exactly
the right length, but rather, to calculate a length which could be easily
shown to be definitively long enough.
I am, however, pretty happy with this part:
          for (s = new_environs.template; t = strchr(s, '%'); s = t + 2) {
            u += snprintf(u, (len - (u - new_environ)), "%.*s%s",
                          t - s, s, parent_path);
          }

Note that I don't check, in this version, whether it's "%s" or some other
character after a %.  This was one of those "we need something within half
an hour that will work for this circumstance, we can clean it up tomorrow"
jobs.
-s
p.s.:  Side note for Unix users:  Yes, it's okay to free the argument to
setenv after passing it in, unlike putenv().

Gee, Peter, what does this prove?

You can write a trivial piece of code?

But it has a bug, as you yourself point out. Why should you not be
exposed to the same scorn you showed Herb?

The code looks incorrectly for %s in two places, so the bug is doubled
in its effect.

Oh yes, and you don't check malloc for failure.

The SAME sort of nits exist in this code as exist in Herb. Are we to
forgive you? Sure, you needed the first draft in a half hour, but you
could have posted a cleaned up version.

But, then you would have found that your basic approach looks for %s
in two different places. It's gonna get nasty when you get around to
it.

Actually checking for %s and not % means that you should have done
things in one pass, not a pass to determine the malloc request and a
pass to create the output string. Instead, you needed to create a
linked list of output string segments whilst calculating the size of
the final malloc. This way the second pass would have reduced to just
tying the segments together without repeating the strchr searches for
% (and the extra checks for a following s).

Alternatively, you could have malloc'd for the worst case and done
everything in one pass. This would have been imagining that the input
string consisted of nothing but %s sequences, and mallocing its length
halved times the substitute string length plus one for Nul, then
freeing all the storage you don't need.

Even better, you would have written the code as a replace function
handling anything, using a linked list or worst case malloc which
assumes that the input string is a series of the strings to be
replaced.

Even better, you would have replaced ALL string handling by something
that actually works, emulating the best C programmers, who always find
themselves trying to exit the Truman Show that is C by using C to
create something else.


A mediocre programmer, Seebs, believes he's actually analyzing a
problem when he reduces it to a simpler problem by changing the
requirements.

Here, you knew that "it's much easier to strchr search for a
character, than it is to search for a 'string', that is a sequence of
characters inside a C string that is not Nul terminated itself".

Therefore IMO and as far as I can tell, you blundered forward and
solved the wrong, if simpler problem: "replace all occurences of
percent".

But that wasn't the requirement. You needed to "replace all occurences
of the string '%s'".

You knew what you were doing, but when we return to fix your bug, we
find that actually fixing it involves slightly elaborate code in two
places.

One way would be to use a macro to handle this, but the need shows us
that your basic "two pass" method is just not right. Coding the
solution as a general replace() function causes us to ask why this
cannot be done in less than two passes...perhaps one and one half
passes, as in the linked list, or, if storage is cheap, one pass
followed by freeing the storage acquired in our worst case malloc.

However, the most storage-elegant solution would be to create a linked
list of all sequences that do not contain %s (in the specialized
version) or the string to be replaced (in a generalized replace).
 
S

Seebs

I notice that you use "++i" where I think the majority of C
programmers would write "i++". What's your rationale for doing so?
I prefer ++i myself, but my reasons for doing so seem a bit flimsy,
and I wonder whether I should just follow the majority ....

A couple of things:

1. In my native language (English), "increment i" is more idiomatic than
"i increment", so it's easier to pronounce.
2. The semantics of ++i are simpler than the semantics of i++. To simplify
if I do not explicitly need a postincrement, I use a preincrement.

The first was suggested to me by a college friend somewhere in the very early
90s or late 80s, the second is something I picked up with experience. I like
to think I'm pretty smart, but I have concluded that I am not smart enough
to take on unneeded complexities.

-s
 
S

santosh

Seebs said:
A couple of things:

1. In my native language (English), "increment i" is more idiomatic than
"i increment", so it's easier to pronounce.
2. The semantics of ++i are simpler than the semantics of i++. To simplify
if I do not explicitly need a postincrement, I use a preincrement.

The first was suggested to me by a college friend somewhere in the very early
90s or late 80s, the second is something I picked up with experience. I like
to think I'm pretty smart, but I have concluded that I am not smart enough
to take on unneeded complexities.

Just asking out of interest, would a post-increment enable any
significant optimisations by the compiler that wouldn't be possible
with a pre-increment?

That's about the only reason I can think of for using a post-
increment, other than that it's more idiomatic, in such typical loops.
 
A

Andrew Poelstra

Just asking out of interest, would a post-increment enable any
significant optimisations by the compiler that wouldn't be possible
with a pre-increment?

I doubt it. Many assemblers have an INC instruction, which would
make things probably a little harder for a post-increment.
 
S

spinoza1111

<Some code...>

Seebie posted what I considered a crude, and what he admitted to be a
buggy, solution to the "problem of replacing %s by a string".

He redefined the problem as "searching for a character", in my view
incorrectly, and produced a special-purpose and IMO rather confusing
solution. He admitted that the solution would not work if other
percent sequences or signs existed in the input.

Two hours ago I started to write and to test the following solution,
which is based on my discussion of the failings of Seebie's code, and
my demonstration above in prose that the REAL problem is "replacing a
string, where a string is not terminated by NUL", and that if instead
of "hacking" the problem (reducing it to something we can solve
"simply" whilst creating, as I've shown, a problem when you return to
fix the admitted problem), we actually ANALYZE the problem like men.

The code below does what I propose above: in one pass it finds all the
replacement strings and simultaneously constructs a linked list of
segments outside of replacement strings. In a subsequent half a pass
it assembles the final string.

The code has only been tested for two cases but it's time to let you
slobs have at it.

For the solution following may have bugs, same as Seebie's code had a
bug which he identified. I submit this preliminary version for expert
discussion and bug finding expecially from Bacarisse. I claim that
there is all the difference in the world between a known bug whose fix
is problematic and which shows the wrong approach from the start, and
this code, which is based on a correct problem analysis. This code
gives posterity a replace function whereas Seebie's code (like so much
code written by people without academic training) creates problems.

I left the field for teaching BECAUSE numerous times in my career, at
junctures between "hacking" (the fantasy that changing the problem
requirements to something brutal and stupid is scientific method) and
something seldom seen (thinking "up", outside the box, based on the
critical understanding that we've been given minimal access to the
tools of production and that the only hope is to take those tools and
make them anew), that going in the latter direction is ALWAYS a non-
starter, and ALWAYS met with objections of the form "think like a
manager and not a programmer", followed by the worst sorts of bullying
and abuse as needed.

We've all been there.

"Give the customer something that silently replaces %s and also %
anything in version 1".
"Allocate a fixed size and large buffer in preference to a calculation
that makes my head hurt". "Don't write a small compiler".
"Think like a manager and not an engineer".
"Don't make me THINK".
"Thou shalt not be aware".
"Don't think."
"comp.programming is not about programmers".
"Ha ha ha you have a funny name, Niggardly Bullschildt."
" 'Sblood, thou stinkard, I'll learn ye how to gust ... wolde ye
swynke me thilke wys?... Magna Mater! Magna Mater!... Atys... Dia ad
aghaidh's ad aodaun... agus bas dunarch ort! Dhonas 's dholas ort,
agus leat-sa!... Ungl unl... rrlh ... chchch..."

The "hacker ethos" in fact is merely the name for a privileged, but
ever shrinking, mass of half-educated and unqualified people who hide
behind walls of crap. If it caused the Toyota recall, the shit's gonna
hit the fan when Congressional investigators finally figure out what
it is that programmers do.

My overall critique of Seebie also is meant to demonstrate the truth
of what Hamlet said:

"Vse euerie man after his desart, and who should scape whipping: vse
them after your own Honor and Dignity. The lesse they deserue, the
more merit is in your bountie."

That is, don't shit on Schildt for there is something called Karma. We
ALL have sinn'd mightily.

Here is the code. Hungarian notation is used without apology: note
that string names not intended to be used as pointers start with str,
whereas string pointers intended to be used as such start with ptr. I
will continue to test it and post further improvements as they become
available.


#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
int intReplaceAtEnd;
struct TYPsegmentstruct * ptrNext; };

char * replace(char * strMaster,
char * strTarget,
char * strReplacement)
{
char * ptrIndex0;
char * ptrIndex1;
char * ptrIndex2;
char * ptrIndex3;
char * strNew;
char * strNewStart;
long lngNewLength;
long lngCount;
struct TYPsegmentstruct * ptrSegmentStructStarts;
struct TYPsegmentstruct * ptrSegmentStruct;
struct TYPsegmentstruct * ptrSegmentStructPrev;
ptrIndex1 = strMaster;
ptrSegmentStructPrev = 0;
lngNewLength = 0;
while(*ptrIndex1)
{
ptrIndex0 = ptrIndex1;
for(;
*ptrIndex1 && *ptrIndex1 != *strTarget;
ptrIndex1++);
for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
*ptrIndex3 && *ptrIndex2 && *ptrIndex3 == *ptrIndex2;
ptrIndex3++, ptrIndex2++);
if (!*ptrIndex1 || !*ptrIndex2)
{
if (!(ptrSegmentStruct =
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment = ptrIndex0;
ptrSegmentStruct->lngSegmentLength =
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->intReplaceAtEnd =
!*ptrIndex2 ? -1 : 0;
lngNewLength += ptrSegmentStruct->lngSegmentLength +
(*ptrIndex1
?
strlen(strReplacement)
:
0);
ptrSegmentStruct->ptrNext = 0;
if (ptrSegmentStructPrev != 0)
ptrSegmentStructPrev->ptrNext = ptrSegmentStruct;
else
ptrSegmentStructStarts = ptrSegmentStruct;
ptrSegmentStructPrev = ptrSegmentStruct;
}
ptrIndex1 = ptrIndex3;
}
if (!(strNewStart = malloc(lngNewLength + 1))) abort();
strNew = strNewStart;
ptrSegmentStruct = ptrSegmentStructStarts;
while (ptrSegmentStruct)
{
for (ptrIndex1 = ptrSegmentStruct->strSegment,
lngCount = 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew = *ptrIndex1;
if (ptrSegmentStruct->intReplaceAtEnd)
for (ptrIndex1 = strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew = *ptrIndex1;
ptrSegmentStruct = ptrSegmentStruct->ptrNext;
}
*strNew = '\0';
return strNewStart;
}

int main()
{
printf("\nReplace\n\n\n");
printf("Expect a miracle:\n\"%s\"\n\n",
replace("a stupid error", "stupid error", "miracle"));
printf("Expect a miracle error:\n\"%s\"\n\n",
replace("a stupid error", "stupid", "miracle"));
return 0;
}
 
S

spinoza1111

spinoza1111  said:
Can't you just let Moore's Law handle "efficiency"?
interesting question.
It is.
FWIW:  You can't.
First off, Moore's Law doesn't expand as fast as some particularly
expensive operations do.  Secondly, even if it does expand with the right
big-O relation, it may not expand fast enough to do much good.
<snip>
[...] your comment is nonsense, and I don't think you
understand computational complexity, for if "it" expands with "the
right big O relation", then it follows that this is fast
enough...
what's the "right" big O notation?
although in fact, we shouldn't rely on Moore's Law to justify
the use of mathematically slow algorithms, and that was not implied by
the original post. We weren't discussing buying faster computers so as
to code bubble sort, we were discussing running effective algorithms
faster.
not all problems have a known "good" (polynomial) algorithm. Think NP
complete (travelling salesman etc.). I gave you a bunch of examples in
Traveling salesman has a "good" algorithm. It's called simulated
annealling.

Which gives an approximate solution, no?  because the existence of
a polynomial-time algorithm for the TSP as stated in discussions of
computational complexity and NP-completeness form would be big news.

That's correct. However, the approximate solution is very useful and
according to my information in use. I recall a logistics system
written by my employer in the 1970s, before the science was
understood, that "seemed to loop" when it was given real routes to
plan. Later on, my brother's firm, a trucking firm, used the simulated
annealling algorithm.

Moore's law won't help us much with NP complete solutions. And as
Chris points out it may run out of gas. Because of the need to master
parallelism and avoid problems such as the Toyota recall (IF that was
caused by a software bug, as Steve Wozniak has suggested), computer
programmers by 2025 may have to have PhDs. That might be a good thing.
I worked at Motorola in 1979. Years later, a Siemens engineer told me
that the reason Motorola didn't have a marketable cellphone in 1975
was that under Nixon, the FCC was to embroiled in politics as a
consequence of Vietnam and Watergate that it would not release
frequencies needed to implement cellphones.

[ snip ]
 
S

spinoza1111

A couple of things:

1.  In my native language (English), "increment i" is more idiomatic than
"i increment", so it's easier to pronounce.
2.  The semantics of ++i are simpler than the semantics of i++.  To simplify
if I do not explicitly need a postincrement, I use a preincrement.

The first was suggested to me by a college friend somewhere in the very early
90s or late 80s, the second is something I picked up with experience.  I like
to think I'm pretty smart, but I have concluded that I am not smart enough
to take on unneeded complexities.

No argument there.

However, Peter, over my thirty year career in programming I did notice
that many programmers, myself included, developed tics over trivial
matters. Like "Turkey" and "Ginger Nut" in Herman Melville's short
story "Bartelby the Scrivener", programmers, deprived of access to the
means of production except by ways and means that were ever more
controlled, seem to obsess over nonsense and to describe the
occasional survival of humanity as "looney".

I don't care what sort of standalone increment you use, since an
equally valid argument could be constructed for never using either
operator at all, and always writing i += 1.

Ah Bartleby! Ah humanity!
 
S

spinoza1111

spinoza1111wrote:




Here is the first problem.

Richard, stay out of the discussion unless you can identify each
problem properly in the response. Newbies deserve to hear what little
wisdom you have.

Here, you're deliberately creating confusion like the Office Asshole
in the structured walkthrough, since I don't want to widen the search
for stdio.h or malloc.h.

Either explain why you think the code is wrong or LEAVE.
 
S

spinoza1111

spinoza1111wrote:


I'm pretty sure I've explained the above to you in nauseous detail on at
least one previous occasion. Go look it up in the archives.

You've explained your opinion. We want to hear it again, because we
tend to forget so many of your opinions, they being worthless in too
many cases. From three sources (msdn, wikipedia, and gcc) I see that
the angle brackets are more restrictive and that's what I want.

As the Asshole in Residence you prefer to spread suspicion about
people's qualifications. I'm calling you out. I've shown how you
failed to do well in a simple test, and you've lied about my presence
in comp.risks. Here, I have returned to C after several years because
I want you to either change your behavior or leave.
 
S

spinoza1111

You've explained your opinion. We want to hear it again, because we
tend to forget so many of your opinions, they being worthless in too
many cases. From three sources (msdn, wikipedia, and gcc) I see that
the angle brackets are more restrictive and that's what I want.

As the Asshole in Residence you prefer to spread suspicion about
people's qualifications. I'm calling you out. I've shown how you
failed to do well in a simple test, and you've lied about my presence
in comp.risks. Here, I have returned to C after several years because
I want you to either change your behavior or leave.

By calling Richard "Asshole in Residence" I violate my own charter
posted elsethread. This is because like the United Nations Charter we
have the right of self-defense, verbal here, against aggression.
Richard Heathfield has a track record of posting negatives about code
submission here without explanation in such a way as to cast
aspersions on professionalism in a newsgroup which needs collegiality.

What Habermas calls communities of civil discourse do not function
well until all people not committed to the charter leave. This
directly contradicts openness but I don't see any other solution.

But: I shall cease all namecalling at this time, and use code and
argument as self-defense. My apologies to all.
 
S

santosh

spinoza1111 wrote:
Seebie posted what I considered a crude, and what he admitted to be a
buggy, solution to the "problem of replacing %s by a string".

He redefined the problem as "searching for a character", in my view
incorrectly, and produced a special-purpose and IMO rather confusing
solution. He admitted that the solution would not work if other
percent sequences or signs existed in the input.

Two hours ago I started to write and to test the following solution,
which is based on my discussion of the failings of Seebie's code, and
my demonstration above in prose that the REAL problem is "replacing a
string, where a string is not terminated by NUL", and that if instead
of "hacking" the problem (reducing it to something we can solve
"simply" whilst creating, as I've shown, a problem when you return to
fix the admitted problem), we actually ANALYZE the problem like men.

The code below does what I propose above: in one pass it finds all the
replacement strings and simultaneously constructs a linked list of
segments outside of replacement strings. In a subsequent half a pass
it assembles the final string.

The code has only been tested for two cases but it's time to let you
slobs have at it.
Here is the code. Hungarian notation is used without apology: note
that string names not intended to be used as pointers start with str,
whereas string pointers intended to be used as such start with ptr. I
will continue to test it and post further improvements as they become
available.


#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

struct TYPsegmentstruct
{ char * strSegment;
long lngSegmentLength;
int intReplaceAtEnd;
struct TYPsegmentstruct * ptrNext; };

char * replace(char * strMaster,
char * strTarget,
char * strReplacement)
{
char * ptrIndex0;
char * ptrIndex1;
char * ptrIndex2;
char * ptrIndex3;
char * strNew;
char * strNewStart;
long lngNewLength;
long lngCount;
struct TYPsegmentstruct * ptrSegmentStructStarts;
struct TYPsegmentstruct * ptrSegmentStruct;
struct TYPsegmentstruct * ptrSegmentStructPrev;
ptrIndex1 = strMaster;
ptrSegmentStructPrev = 0;
lngNewLength = 0;
while(*ptrIndex1)
{
ptrIndex0 = ptrIndex1;
for(;
*ptrIndex1 && *ptrIndex1 != *strTarget;
ptrIndex1++);
for(ptrIndex2 = strTarget, ptrIndex3 = ptrIndex1;
*ptrIndex3 && *ptrIndex2 && *ptrIndex3 == *ptrIndex2;
ptrIndex3++, ptrIndex2++);
if (!*ptrIndex1 || !*ptrIndex2)
{
if (!(ptrSegmentStruct =
malloc(sizeof(struct TYPsegmentstruct))))
abort();
ptrSegmentStruct->strSegment = ptrIndex0;
ptrSegmentStruct->lngSegmentLength =
ptrIndex1 - ptrIndex0;
ptrSegmentStruct->intReplaceAtEnd =
!*ptrIndex2 ? -1 : 0;
lngNewLength += ptrSegmentStruct->lngSegmentLength +
(*ptrIndex1
?
strlen(strReplacement)
:
0);
ptrSegmentStruct->ptrNext = 0;
if (ptrSegmentStructPrev != 0)
ptrSegmentStructPrev->ptrNext = ptrSegmentStruct;
else
ptrSegmentStructStarts = ptrSegmentStruct;
ptrSegmentStructPrev = ptrSegmentStruct;
}
ptrIndex1 = ptrIndex3;
}
if (!(strNewStart = malloc(lngNewLength + 1))) abort();
strNew = strNewStart;
ptrSegmentStruct = ptrSegmentStructStarts;
while (ptrSegmentStruct)
{
for (ptrIndex1 = ptrSegmentStruct->strSegment,
lngCount = 0;
lngCount < ptrSegmentStruct->lngSegmentLength;
ptrIndex1++, lngCount++, strNew++)
*strNew = *ptrIndex1;
if (ptrSegmentStruct->intReplaceAtEnd)
for (ptrIndex1 = strReplacement;
*ptrIndex1;
ptrIndex1++, ++strNew)
*strNew = *ptrIndex1;
ptrSegmentStruct = ptrSegmentStruct->ptrNext;
}
*strNew = '\0';
return strNewStart;
}

int main()
{
printf("\nReplace\n\n\n");
printf("Expect a miracle:\n\"%s\"\n\n",
replace("a stupid error", "stupid error", "miracle"));
printf("Expect a miracle error:\n\"%s\"\n\n",
replace("a stupid error", "stupid", "miracle"));
return 0;
}

It doesn't compile here. I'm using gcc 4.3.3 on Ubuntu 9.04.

$ gcc -o spinoza1111 spinoza1111.c
spinoza1111.c:27:16: error: invalid suffix "D" on integer constant
spinoza1111.c: In function ‘replace’:
spinoza1111.c:27: error: expected ‘;’ before ‘strMaster’
spinoza1111.c:28:27: error: invalid suffix "D" on integer constant
spinoza1111.c:28: error: expected ‘;’ before numeric constant
spinoza1111.c:29:19: error: invalid suffix "D" on integer constant
spinoza1111.c:29: error: expected ‘;’ before numeric constant
spinoza1111.c:32:20: error: invalid suffix "D" on integer constant
spinoza1111.c:32: error: expected ‘;’ before ‘ptrIndex1’
spinoza1111.c:34:40: error: invalid suffix "D" on integer constant
spinoza1111.c:36:24: error: invalid suffix "D" on integer constant
spinoza1111.c:36: error: expected ‘;’ before ‘strTarget’
spinoza1111.c:36:49: error: invalid suffix "D" on integer constant
spinoza1111.c:37:53: error: invalid suffix "D" on integer constant
spinoza1111.c:37:56: error: invalid suffix "D" on integer constant
spinoza1111.c:41:37: error: invalid suffix "D" on integer constant
spinoza1111.c:42: error: expected ‘)’ before ‘malloc’
spinoza1111.c:44:43: error: invalid suffix "D" on integer constant
spinoza1111.c:44: error: expected ‘;’ before ‘ptrIndex0’
spinoza1111.c:45:49: error: invalid suffix "D" on integer constant
spinoza1111.c:46: error: expected ‘;’ before ‘ptrIndex1’
spinoza1111.c:47:48: error: invalid suffix "D" on integer constant
spinoza1111.c:48: error: expected ‘;’ before ‘!’ token
spinoza1111.c:49:28: error: invalid suffix "D" on integer constant
spinoza1111.c:49: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:55:40: error: invalid suffix "D" on integer constant
spinoza1111.c:55: error: expected ‘;’ before numeric constant
spinoza1111.c:56:40: error: invalid suffix "D" on integer constant
spinoza1111.c:56: error: expected ‘)’ before numeric constant
spinoza1111.c:57:48: error: invalid suffix "D" on integer constant
spinoza1111.c:57: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:59:41: error: invalid suffix "D" on integer constant
spinoza1111.c:59: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:60:35: error: invalid suffix "D" on integer constant
spinoza1111.c:60: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:62:20: error: invalid suffix "D" on integer constant
spinoza1111.c:62: error: expected ‘;’ before ‘ptrIndex3’
spinoza1111.c:64:24: error: invalid suffix "D" on integer constant
spinoza1111.c:64: error: expected ‘)’ before ‘malloc’
spinoza1111.c:65:13: error: invalid suffix "D" on integer constant
spinoza1111.c:65: error: expected ‘;’ before ‘strNewStart’
spinoza1111.c:66:23: error: invalid suffix "D" on integer constant
spinoza1111.c:66: error: expected ‘;’ before ‘ptrSegmentStructStarts’
spinoza1111.c:69:25: error: invalid suffix "D" on integer constant
spinoza1111.c:69: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:70:24: error: invalid suffix "D" on integer constant
spinoza1111.c:73:23: error: invalid suffix "D" on integer constant
spinoza1111.c:75:29: error: invalid suffix "D" on integer constant
spinoza1111.c:75: error: expected ‘;’ before ‘strReplacement’
spinoza1111.c:78:27: error: invalid suffix "D" on integer constant
spinoza1111.c:79:27: error: invalid suffix "D" on integer constant
spinoza1111.c:79: error: expected ‘;’ before ‘ptrSegmentStruct’
spinoza1111.c:81:14: error: invalid suffix "D" on integer constant
spinoza1111.c:81: error: expected ‘;’ before '\x0'

How did it compile for you? Which compiler and what options did you
use?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top