4 ms·
Don't use `strncpy()` and `strncat()` at all, use snprintf(buffer, buffer_len, "%s Stuff %s", str1, str2); It's safe (C99, C++11) and easily extendible. F
by vortico 8y ago
Don't use `strncpy()` and `strncat()` at all, use
snprintf(buffer, buffer_len, "%s Stuff %s", str1, str2);
It's safe (C99, C++11) and easily extendible. Format strings are fun!
Not the fastest, but if the bottleneck of your program is concatinating strings, just do it manually.
- Hello71 8y agoThis is a safe, if slow, alternative for strncpy, but it does not safely replace strncat. The C standard does not define the behavior if the code "sprintf(buf, "%s some further text", buf);" is used.
- dmitrygr 8y ago#define strncat(a, b, maxlen) snprintf(a + strlen(a), maxlen - strlen(a), "%s", b)
- kazinator 8y agoToo many evaluations of a. If you have snprintf, you probably have inline functions. One day someone will do something like strncat(a += previous_delta, ...).
- dmitrygr 8y agoOPTION 1 (c): char* mystrncat(char *a, const char *b, size_t maxlen){ snprintf(a + strlen(a), maxlen - strlen(a), "%s", b); return a; } OPTION 2 (gccism): #define strncat(_a, b, maxlen) ({char* a = _a; snprintf(a + strlen(a), maxlen - strlen(a), "%s", b); _a;})
- vortico 8y agoRight, don't use `buf` as an input and output with `snprintf`. A lot of people use `str(n)cat` and `str(n)cpy` together like char *a; char *b; char *c; strcpy(c, a); strcat(c, b); and I meant that `snprintf` can replace that. But if you actually only have two strings, one with a larger buffer than what it contains, and one to be concatinated, then you can't use `snprintf` like that.
- legulere 8y agoStrncpy gives back the length copied which you can use to append more text: char buf[1024]; size_t pos = 0; int ret = snprintf(buf, sizeof(buf), src1); if(ret >= 0) { pos += ret } else { error() } ret = snprintf(buf + pos, sizeof(buf) - pos, src2); ...
- kazinator 8y agoC99 also introduced swprintf for wide char strings, with a different return value convention. Just to add to the pain when you change char to wchar. Under swprintf, and related functions, %s still takes a char pointer, not wchar_t! So when you make everything wide, you have to edit all the %s to %ls.
- haldean 8y agoIt's a good solution for strncat for sure! I'd guess that the majority of strncpy calls look something like: char *x = calloc(n, 1); strncpy(x, y, n - 1); Which can be replaced with: char *x = strdup(y); Which is both one line shorter and 100% less error prone!