S
Stefan Ram
Ben Bacarisse said:and while (i-- & other_condition(i)) is idiomatic for counting while
There might be a typo above: »&« possibly was intended to be »&&«.
Ben Bacarisse said:and while (i-- & other_condition(i)) is idiomatic for counting while
There might be a typo above: »&« possibly was intended to be »&&«.
Which is basically something like
n := strlen(s)
while n>0 and isspace(s[n-1]),
s[--n] := 0
However an important gotcha is the string has to be writable and all
clients of
the string will see the trimming. If you may want to make a copy of the
string
and modify that.
Which is basically something like
n := strlen(s)
while n>0 and isspace(s[n-1]),
s[--n] := 0
However an important gotcha is the string has to be writable and all clients of
the string will see the trimming. If you may want to make a copy of the string
and modify that.
Example prototype:
I do sometimes use my own little library that accepts const string andOh yeah, you wouldn't want to spoil the functional purity of C programming with
an underhanded destructive hack, such as trimming a string in place!
Too much editing and the prototype disappeared! It might look like:
int trimstringright(char* str, int length);
(size_t can be used, if an alternative to -1 for the length can be found.)
Here's some code, although not as efficient as it could be when no length is
provided:
int trimstringright(char* str, int length){
char *p;
if (str==NULL)return 0;
if (length==-1) length=strlen(str); //being lazy..
if (length==0) return 0;
p=str+length-1;
while (p>=str && *p-- == ' ') --length;
return length;
}
Consider trimstringright(" ",1);
Just before the while loop, length==1 and p==str.
In the first iteration, the loop condition holds,
and p is decremented and now points outside the string.
In the second iteration, the access to p in "p>=str"
has undefined behaviour.
BartC said:[Scanning a string backwards]
Consider trimstringright(" ",1);
Just before the while loop, length==1 and p==str.
In the first iteration, the loop condition holds,
and p is decremented and now points outside the string.
In the second iteration, the access to p in "p>=str"
has undefined behaviour.
OK, let's suppose that on some machine, it is meaningless to point to
an address before 'str'; why would the problem occur on the next
access to p, rather than in the p-- operation, or in the >=
comparison?
And, on a machine which doesn't have such problems (eg. flat address
space,
str not located at the beginning of that space, and the ability
to compare pointers even when the memory locations involved do not
exist), would it still be undefined behaviour?
Yes. "It works" is in fact the most dangerous form of undefinedAnd, on a machine which doesn't have such problems (eg. flat address space,
str not located at the beginning of that space, and the ability to compare
pointers even when the memory locations involved do not exist), would it
still be undefined behaviour?
Yes. "It works" is in fact the most dangerous form of undefined
behaviour.
And, on a machine which doesn't have such problems (eg. flat address space,
str not located at the beginning of that space, and the ability to compare
pointers even when the memory locations involved do not exist), would it
still be undefined behaviour?
Hah hah. Of course, I understand this phrase in the CLC context, but I have
to point out that I think most working code in the real world does, in fact,
have undefined behavior coursing through its veins.
Yes, thanks. Glad I followed protocol in posting an error in a
correction
Ben Bacarisse said:Both here and below you meant to write isspace(*p).
No, that has a similar problem. Unfortunately you've cut the context so
it won't be clear what you were correcting. The problem was
constructing an invalid pointer that points before the start of the
string and this code can also do that when the string is all spaces.
In addition to being careful about the pointers, you need to finesse the
mess that is isspace (and friends) when char might be signed. It's a
shame that what should be a simple function is really quite tricky.
char *rstrip(unsigned char *string)
{
char *ep = strchr(0);
while (ep > string && isspace(ep[-1])) --ep;
*ep = 0;
return string;
}
(The unsigned char * just is to avoid cluttering the code with a cast
or Tim's exotic compound literal union.)
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.