Groovy hepcat Olivier Bellemare was jivin' on Sat, 06 Dec 2003
03:25:58 GMT in comp.lang.c.
Getting the middle of a string's a cool scene! Dig it!
I've tried to make a function that returns the middle of a string. For
example:
strmid("this is a text",6,4); would return "is a".
Here is my code:
char *strmid(char *texte, int depart, int longueur)
Avoid function names beginning with "str". They are reserved
identifiers. (To be more precise, all identifiers with external
linkage beginning with "str" followed by a lower case letter are
reserved.)
{ char *resultat = " ";
char *temporaire = " ";
int nbr;
nbr = depart + longueur - 1;
strncat(temporaire,texte,nbr);
Uh oh! You've just caused undefined behaviour. First of all,
temporaire points to a string literal, which may be in memory marked
read only. You are attempting to modify this string literal. This can
cause a crash. And secondly, even if you can modify the string literal
without problems, you have another problem. Your string literal is
only 2 bytes long (one byte for the space and one byte for the
terminating null character). But you are attempting to add more bytes
to the end of it. Result: you are writing into some random memory
location. This also produces undefined behaviour.
On top of that, your string literal contains a space, and you are
attempting to append a string to the end of this string literal. So,
even if the operation succeeded, you'd end up with a space at the
start of the resulting string, which isn't in the original string. I'm
sure this is not desired.
There's no such function in standard C, and I don't see a
declaration of this in your code, let alone a definition. (And it's a
reserved identifier anyhow. See above.)
strncat(resultat,temporaire,longueur+1);
And once again you are attempting to modify a string literal and
write beyond the end of it. But here you have yet another problem.
Both temporaire and resultat point at a string literal with the same
content. These two string literals are allowed to be folded into one.
In that case, you're writing a string to the end of itself. This is a
big problem.
But that's not all. strncat() doesn't always append a null character
to the end of the sequence, so it may not be a string. (Remember, a
string ends with a null character.)
See above.
Note: if you return (the address of the first element of) an array
with automatic duration, you will have another problem. Automatic
variables no longer exist after the function returns. String literals
have static duration, however. But, as I've already shown, string
literals cause other problems.
}
It doesn't work properly, but I really don't understand why. Can anyone
enlighten me? Or, if there's a similar code that works already, can I have
it please?
Sure, here you go. I've included functions that get the rightmost
and leftmost parts of a string too, in case you need them at some time
in the future.
#include <assert.h>
#include <stdio.h>
#include <string.h>
/* copies 'len' characters from offset 'off' of string 'src' to 'dst'
returns dst */
char *substr(char *dst, const char *src, int off, int len)
{
assert(NULL != dst);
assert(NULL != src);
assert(0 <= len);
assert(0 <= off);
sprintf(dst, "%.*s", len, src + off);
return dst;
}
/* copies rightmost 'len' characters from 'src' to 'dst'
returns dst */
char *rightstr(char *dst, const char *src, int len)
{
const char *p;
int sl;
assert(NULL != dst);
assert(NULL != src);
assert(0 <= len);
if(len >= (sl = strlen(src)))
p = src;
else
p = src + sl - len;
sprintf(dst, "%.*s", len, p);
return dst;
}
/* copies leftmost 'len' characters from 'src' to 'dst'
returns dst */
char *leftstr(char *dst, const char *src, int len)
{
assert(NULL != dst);
assert(NULL != src);
assert(0 <= len);
sprintf(dst, "%.*s", len, src);
return dst;
}
--
Dig the even newer still, yet more improved, sig!
http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?