trim whitespace v3

S

Seebs

Seebs treats people like video game characters,

No, I don't.
then questions why not
everyone will tolerate it.

No, I don't.
He thinks his knowledge is so valuable that
it should excuse anything he says.

No, I don't.

I fully expect people to complain about me being a jerk sometimes, since
I'm sometimes a jerk. It's a long-term work in progress. I'm a lot nicer
than I used to be, and I expect to continue becoming nicer for some time.

On the other hand, I also notice that a lot of people are pretty happy
with the way I act near them, since I'm friendly and polite. One thing these
people have in common is that they aren't generally Usenet trolls with a
history of trying to "learn" in a way that does not include any willingness
to actually, well, learn.

If you're demanding that people answer specific technical questions without
regard to context, you're not trying to learn.
Common sense says, what goes around, comes around. Or if you understand
farming, you can only reap what you sow.

True enough. And yet, a large number of people across multiple fora react
to you with hostility, and you haven't figured out the common element. Hint:
Your high-handed attitude with people you're asking for help does not work
well.

-s
 
A

Andrea

Seebs said:
// test case

char s0[] = " space both sides ";
char s1[] = "trailing space ";
char s2[] = " leading space";
char s3[] = " spaces both sides ";
char s4[] = "\n\t\rspecial trim both sides\n\t\r";
char s5[] = " \n\t\r special trim before";
char s6[] = "special trim after\n\t\r ";
char s7[] = "no trimming";
char s8[] = " ";
char s9[] = "";

char *strings[11] = {
s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, NULL
};

Why not:
char *strings[] = {
" space both sides ",
"trailing space ",
...,
NULL
};

no, cause his version need modificable string to be passed to his trim
function
for (i = 0; i < 11; i++) {

and then:
for (i = 0; strings; ++i) {


no, cause his version pass the null pointer to the trim function

hell, he is the only one who posted a single pass version of the trim
function, and all the comment he get is that crap above?

your incompetence is just a bit less scary than your religious
intolerance
 
S

Seebs

no, cause his version need modificable string to be passed to his trim
function

That could be done, then, as
char strings[][99] = {
...
}

Point is, you don't need to explicitly declare all those things as variables,
C is quite capable of doing an array with initializers that produces
modifiable strings.
no, cause his version pass the null pointer to the trim function

I couldn't tell whether that was intentional or not, but it's trivial
to fix -- the point being, getting rid of the explicit counting of the
number of strings is a good deal. If you want to test the null pointer,
you can do it with a do-while, or you can just call
trim(NULL);
at the end.

It's better than, say, adding or removing a test case, and having to
remember to go fix a magic number elsewhere in the code.
hell, he is the only one who posted a single pass version of the trim
function, and all the comment he get is that crap above?

Guess so?
your incompetence is just a bit less scary than your religious
intolerance

My what?

-s
 
S

Shao Miller

Seebs said:
Why so personal? I can be a real grade-A jerk, but I happen to know a
fair bit about the subject matter, and I'm usually pretty willing to
answer interesting questions.

Now, I recognize that you don't read my posts, but I suppose this is
something that I think is of use to general readers, whether they program
in C or not:

If you want to learn, it is nearly always devastatingly bad form to
write people off based on personality conflicts. If someone knows the
material, pay attention to what they have to say, and if they annoy
you, deal with it on your own time. As you say, life is short; you
don't have time to be a prima donna. If the advice you need is available
from an asshole, it's time to learn to filter content from the writing
of an asshole.

Robustness in the face of poor behavior is a core skill for ANYONE who
wants to learn to program, or really, who wants to do anything which
may at some point involve other people. It's not an optional thing that
comes long after developing skill at the field.
Ahem.
 
N

Nick Keighley

[discussing errno macros]
Right.

I'm not suggesting that he #inlcude low-level headers.  But that can
help him learn where the constants reside, and then backtrack to figure
out what main headers are needed, if the constants exist somewhere in
his environment.

why would you want to that? I've programmed on both unix (several
varieties) and Windows (and some even stranger systems) and I'm happy
to say I don't know anything about the low level header stuff. You
seem to be encouraging non-portable programming techniques for... er
for what exactly? To shave a pico-second off your build time?
 
N

Nick Keighley

On Mon, 23 Aug 2010 23:01:16 +0200, "Francesco S. Carta"




The Open Group Base Specifications Issue 6
IEEE Std 1003.1, 2004 Edition

It lists common symbolic constants.  Seems like any gcc environment
would have them.

gcc is not posix
If I find many environments lacking EOVERFLOW, I may use a different
symbolic constant.  But if MinGW is the only platform lacking it, that
problem can wait.


--------------------Configuration: trim - Win32
Debug--------------------
Compiling...
trim.c
D:\bin\net\trim.c(13) : fatal error C1189: #error : "EOVERFLOW is not
defined"
Error executing cl.exe.

trim.exe - 1 error(s), 0 warning(s)

An old version of VCC
 
N

Nick Keighley

One way I use it is to trim whitespace from command line arguments in
argv.  I don't want to change the argv pointer list, so I change the
data in place.

is the data in argv necessarily modifiable/ (I've no idea, I'm asking)


<snip>
 
N

Nick Keighley

Microsoft uses glibc?  I never knew!

Why not before you hand over your credit card to buy a copy of MSVC
you ask them to make their C library actually C99 compatible [or heck
at least C90 compatible] and get what you actually pay for.

in what sense is it not C90?
 
N

Nick Keighley

On 2010-08-23, Tom St Denis <[email protected]> wrote:
That sounds like it'd be expensive and involve new allocations.

allocation. Singular.

Trim removes bytes and never adds them, so you need to allocate one
buffer the size of your input... let's see...

char *trim(const char *src)
{
char *tmpdst, *dst = calloc(1, strlen(src) + 1);
if (!dst) return NULL;
tmpdst = dst;
while (*src) {
switch (*src) {
case ' ':
case '\n':
case '\t':
break;
default:
*tmpdst++ = *src;
}
++src;
}
return dst;
}

Done. Wow that's hard. Didn't involve 100s of lines of code, is
portable, simple to extend/change, etc.

Inside your argv[] reader you could do this

for (i = 1; i < argc; i++) {
char *tmp = trim(argv);
assert(tmp != NULL);
parse_opt(tmp);
free(tmp);
}

Incredible!
My guess is that this is intended to be general-purpose, rather than
for use in only one specific context.

I'd still write it that way then do this

int trim_inplace(char *str)
{
char *tmp = trim(str);
if (!tmp) return -1;
assert(strlen(str) <= strlen(tmp)); // sanity check


did you test this code?

strcpy(str, tmp);
free(tmp);
return 0;

}

OMG!!! Hierarchical programming!

That's what separates a developer from a coder. In 27 lines of code
[both functions] I replaced what took him 100s of lines. And my
version has error checking, uses standard C functions, is portable,
and is plenty easy to read.

and wrong. This rant would have been so much more impressive if your
code actually met the spec. Your code removes *all* spaces. That isn't
what Mr Kelly meant by "trim" (I don't necessarily agree with his
definition but he gets to decide what the code is supposed to do).

testing StDenis trim function...
TEST FAILED! for input <<hello world>> expected <<hello world>> but
actually <<helloworld>>
 
N

Nick Keighley

True.  But!  If what you say is correct, then *the code is wrong*.  And
that's the thing -- people don't care that your program does exactly what
you coded it to do, they care whether it does what you told them it would
do.

A sufficient description to be able to predict the output of a function
without reading its source is pretty valuable, and I think effectively
essential; without it, the code is useless.

You have mentioned interest in developing a stable library of solutions
like this one.  Well, stage one in that will be to come up with definitions
sufficiently useful that people COULD use the functions, because without
those definitions, there's no value to them in the functions.


Okay, imagine that we are to look at Tom's trim() function which strips
internal whitespace also.

Is that a bug that we should fix?  How would you know, without a spec
a little more detailed than "remove whitespace"?

I know John Kelly is annnoying but you really should criticise for
what he *actually* does rather than what you think he does.

From his post at the beginning of this thread
"Trim leading and trailing whitespace from any null terminated
string[...]"

So, yes, Tom St Denis's version *is* wrong!
 
N

Nick Keighley

What?  Was that in one of the versions you posted?


If I have to read the code to know how to use your function, I'm not
interested in using it.

well up to a point. In order to know exactly what it does you are
going to have to read the code. Or you are going to have to read
something that is logically equivalent to the code. Why write it
twice?

The DRY ("Don't Repeat Yourself") Principle.

Admittedly for simple functions like trim() it whould be possible to
produce a simple specification.
 
N

Nick Keighley

... or ... you can just not post the "go somewhere else to find an
answer," and of course leave that place unnamed.  In the Southwest, we
just usually say <badword>.

you're Cornish?

Sometime sit's helpful to direct people to the correct newsgroup. Or
even just tell 'em they're in the wrong one.

[...] I googled [Seebs]:

http://i34.tinypic.com/35hkdwg.jpg

One thing I learned in so doing is that you are an englishman.  

I don't think so
I didn't
know that, but that is the nationality of the majority of Topic Fundies
in c.l.c., so that would make sense.

for the record. *I'm* english.

However, you looked like a guy I would be friends with in real life.  I
was honestly expecting you to be twenty years older and freakishly
scarred or malformed.  Why is that?

I think you (or your psychiatrist) are the only ones who can answer
that

Peter, a person's C source is more personal than poetry.

no.

<snip>
 
N

Nick Keighley

Hmm.  This does mean that you necessarily do two passes through the
string; an in-place operation only has to do one.


This is incorrect.  The original trim() trims only left and right whitespace,
NOT whitespace in the middle of the string.


And at this point, you're iterating over the whole string once to calculate
its length inside trim, once to copy it, twice for the assert, once for
the strcpy...

and once for the calloc()


<snip>
 
B

Ben Bacarisse

Nick Keighley said:
is the data in argv necessarily modifiable/ (I've no idea, I'm asking)

Yes. 5.1.2.2.1 paragraph 2 bullet point 5!

"The parameters argc and argv and the strings pointed to by the argv
array shall be modifiable by the program, and retain their last-stored
values between program startup and program termination."
 
K

Keith Thompson

Nick Keighley said:
well up to a point. In order to know exactly what it does you are
going to have to read the code. Or you are going to have to read
something that is logically equivalent to the code. Why write it
twice?

Because if the behavior of a function is defined only by its
implementation, it's impossible to tell whether it's implemented
correctly.
The DRY ("Don't Repeat Yourself") Principle.

Admittedly for simple functions like trim() it whould be possible to
produce a simple specification.

It should be possible to produce a fairly short specification that
tells you everything you need to know to use it (including what
kinds of arguments need to be avoided).
 
S

Seebs

is the data in argv necessarily modifiable/ (I've no idea, I'm asking)

This marks a topic which has the unusual trait that I once debated it
with Dennis Ritchie, because there's an example in K&R which modifies
the pointers in argv[].

1. argv is a local parameter of main(), so of course main can modify
its local copy.
2. The standard explicitly asserts that the *contents* of the strings
pointed to are modifiable.
3. There is no statement made as to whether or not the pointers in
argv[] are modifiable.

I argue that modifying them ought to be avoided, and/or considered undefined
behavior. Although they are not const-qualified, neither are string literals.
I believe there were, at some point in the past, machines on which messing
with the pointers in argv could affect the behavior of other programs
trying to look at your command line, or something similar -- see the behavior
of, e.g., setproctitle() on BSD systems.

In practice I imagine it's almost certainly harmless, but strictly speaking,
I don't see a guarantee that these pointers can be modified without invoking
undefined behavior.

-s
 
S

Seebs

Yes. 5.1.2.2.1 paragraph 2 bullet point 5!

"The parameters argc and argv and the strings pointed to by the argv
array shall be modifiable by the program, and retain their last-stored
values between program startup and program termination."

This specifies that TWO things are modifiable -- the parameters and the
strings. But there are THREE things -- the parameters, the strings, and
the pointers to the strings that one of the parameters points to.

Sneaky, huh.

-s
 
S

Seebs

and once for the calloc()

I didn't cover that because I've seen implementations where calloc will,
at least sometimes, request pages that are already zero-filled, and I have
used at least one implementation where the kernel uses idle cycles to zero
fill pages in advance, creating a large pool of already-zeroed pages.

So it is POSSIBLE that, in practice, calloc() is O(1).

And some day, when people want an off-topic rant, I should tell the story
of the insanely bad benchmark with calloc() in an inner loop.

-s
 
S

Seebs

[...] I googled [Seebs]:
One thing I learned in so doing is that you are an englishman.  
I don't think so

lolwut

If it helps any, I've *been* to London, twice. As a small child I made one
of the tourist-area guides barely able to keep from laughing after
announcing that I wanted to see the "bloody tower".

It's actually an interesting claim, because I think there is some underlying
truth to it. You can learn a lot about people sometimes by reading their
code. If you know people, you can often tell who wrote a given hunk of code.

-s
 
J

John Kelly

It should be possible to produce a fairly short specification that
tells you everything you need to know to use it (including what
kinds of arguments need to be avoided).

Here:

Define ideas: trim()

Trims leading and trailing whitespace from a null terminated string.
Reports failure and quits if a null terminator is not located within
system defined limit, beginning at the pointer argument.

What else do you need to know?
 

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

Similar Threads

trim whitespace, bullet proof version 63
trim whitespace 194
trim 6
Trim string 42
Request for source code review of simple Ising model 88
Strange bug 65
malloc and maximum size 56
Dead Code? 4

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,286
Latest member
ChristieSo

Latest Threads

Top