patterncMinor
String trim functions with destination size limitation
Viewed 0 times
destinationtrimwithsizelimitationfunctionsstring
Problem
3 string trimming functions:
Trim whitespace from the beginning of a string.
Trim whitespace from the end of a string.
Trim whitespace from both ends of a string.
Looking to improve code for:
-
Correctness (tested code - but so far no holes) - especially overlapping src/dest cases.
-
Design
-
Portability (3 tried: MS, *nix, embedded)
-
Efficiency
Note:
Trim whitespace from the beginning of a string.
Trim whitespace from the end of a string.
Trim whitespace from both ends of a string.
Looking to improve code for:
-
Correctness (tested code - but so far no holes) - especially overlapping src/dest cases.
-
Design
-
Portability (3 tried: MS, *nix, embedded)
-
Efficiency
Note:
(unsigned char) used as unless x==EOF, isspace(x) is not defined when x < 0./* String trim functions
*
* Result is sized limited.
* Overlapping source and destination is OK.
* Pointer parameters are assumed to point to valid strings spaces.
*/
#include
#include
#include
// Return string beginning with first non-white-space in string `src`
// Return NULL when destination is too small, `dest` unchanged.
char *trim_begin(char *dest, size_t dest_size, const char *src) {
while (isspace((unsigned char) *src)) {
src++;
}
size_t src_size = strlen(src) + 1;
if (src_size > dest_size) {
return NULL;
}
return memmove(dest, src, src_size);
}
// Return string beginning string `src` but not including any of its trailing
// white-spaces.
// Return NULL when destination is too small, `dest` unchanged.
char *trim_end(char *dest, size_t dest_size, const char *src) {
size_t len = strlen(src);
while (len > 0 && isspace((unsigned char) src[len - 1])) {
len--;
}
size_t src_size = len + 1;
if (src_size > dest_size) {
return NULL;
}
memmove(dest, src, len);
dest[len] = 0;
return dest;
}
// Return string beginning with first non-white-space in string `src` but not
// including any of its trailing white-spaces.
// Return NULL when destination is too small, `dest` unchanged.
char *trim(char *dest, size_t dest_size, const char *src) {
while (isspace((unsigned char) *src)) {
src++;
}
return trim_end(dest, dest_size, src);
}Solution
-
Repeated code
is a good candidate for a function (
Red face above. I don't know what I was thinking.
-
Portability. A free-standing environment doesn't have to provide
Sorry for nitpicking.
Repeated code
size_t src_size = strlen(src) + 1;
if (src_size > dest_size) {
return NULL;
}
return memmove(dest, src, src_size);is a good candidate for a function (
safe_memmove or something similar).- Optimistic loops
while (isspace((unsigned char) *src))may never stop:'\0'is not a white space. Test for end of string explicitly:
while (*src && isspace((unsigned char) *src))Red face above. I don't know what I was thinking.
-
Portability. A free-standing environment doesn't have to provide
memmove or strlen or isspace. Only features confined in , , , , , , and are mandatory. I am afraid that to claim embedded portability you need to implement optional features yourself.Sorry for nitpicking.
Code Snippets
size_t src_size = strlen(src) + 1;
if (src_size > dest_size) {
return NULL;
}
return memmove(dest, src, src_size);while (*src && isspace((unsigned char) *src))Context
StackExchange Code Review Q#88818, answer score: 4
Revisions (0)
No revisions yet.