To design functions that other programmers will find useful, it helps to draw inspiration from conventions established by existing string libraries.
In C, as in other languages with array indices numbered from 0, it is customary to use inclusive-exclusive ranges.
from would be the index of the first byte to delete;
to would be the index of the first byte to keep. That has the nice property that
to - from indicates the number of characters to be deleted. That convention would echo the
String.substring(beginIndex, endIndex) function that Java offers, for example.
Another common convention in C would be to accept parameters
(str, from, len) — the last parameter specifying the number of bytes to remove.
Finally, you should study Perl's
array.splice(), which are generalized versions of this function.
Starting from the top…
void strdev (char *str, long from, long to)
strdev doesn't mean anything to me. I suggest
char *part1 = malloc(strlen(str) - strlen(&str[from]));
strlen() twice, when you don't need to call it at all.
malloc(from) will do. Since
strlen() works by visiting every byte in the string, you should avoid calling it carelessly.
i is no longer used. Prune the dead code.
memmove(part1, str, from); // New copying
part1 is newly allocated memory, and is guaranteed not to overlap with the source string. Therefore,
memcpy() will do.
sprintf(str, "%s%s", part1, &str[to+1]);
Whoa! Why are you overwriting the initial part of the string with the same characters? You didn't need to do any of that previous work.
The whole function can be condensed down to
char *splice_away(char *str, int from, int to)
memmove(str + from, str + to, 1 + strlen(str + to));
I've used the inclusive-exclusive range convention mentioned above, and added
return str for the caller's convenience.
memmoveinstead of manually copying would be easier, then still add the
'\0'at the end. \$\endgroup\$