Many noob C programmer wonders, why strcat/strcpy return a value, if it's the same, as the 'destination' operand? Isn't it a bit redundant?
char *strcpy(char *dest, const char *src); char *strcat(char *dest, const char *src); void *memcpy(void *dest, const void *src, size_t n);
Mainly for chaining.
At the end of the day, this is used for string construction, without sprintf() and libraries like strbuf (I wrote about it in the C/C++ programming language notes).
This is the best macro I've seen so far. It allocate a buffer for three strings, concatenate them all and return a pointer to it:
#define COMBINETHREESTRINGS( FirstString, SecondString, ThirdString) strcat( strcat( strcpy( _alloca( strlen( FirstString) + strlen( SecondString) + strlen( ThirdString) + 1), FirstString), SecondString), ThirdString)
( WinNT-related-src/leaked-src/XPSP1/sdktools/compdir/compdir.c )
Add file extension:
szFileWSP = strcat( strcpy(szFileWSP , szBaseName ), ".WSP" ); ... szFileTMI = strcat( strcpy( szFileTMI, szBaseName ), ".TMI" );
( WinNT-related-src/leaked-src/Win2K3/sdktools/wst/wstune/wsreduce.c )
Concatenate 3 strings:
strcat(strcat(strcpy(rName.Ptr(), pNS), NAMESPACE_SEPARATOR_STR), pName); ... strcat(strcat(strcpy(rName.Ptr(), pNS), NAMESPACE_SEPARATOR_STR), pclsname); ... strcat(strcat(strcpy(rName.Ptr(), pNS), NAMESPACE_SEPARATOR_STR), pclsname);
( WinNT-related-src/leaked-src/Win2K3/com/netfx/src/clr/vm/tlbexport.cpp )
Construct a string and return the newly constructed buffer:
STATIC char *Cat1(char *s0, char *s1) { return strcat(strcat(Cat0(s0), "\t"), s1); } /* Cat1 */ STATIC char *Cat2(char *s0, char *s1, char *s2) { return strcat(strcat(Cat1(s0, s1), ", "), s2); } /* Cat2 */ STATIC char *Cat3(char *s0, char *s1, char *s2, char *s3) { return strcat(strcat(Cat2(s0, s1, s2), ", "), s3); } /* Cat3 */
( WinNT-related-src/leaked-src/Win2K3/base/mvdm/wow16/sherlock/disasm.c )
// operator+= -- CoolString concatenation of another string: x += y; // Input: CoolString reference // Output: CoolString object concatenated with CoolString contents inline CoolString& CoolString::operator+= (const CoolString& s) { return (strcat (*this, s)); }
( https://github.com/open-watcom/open-watcom-v2/blob/master/bld/plustest/cool/source/string.h )
Add file extensions:
size = strlen( fileprefix); codefilename = MALLOC( size + 6, char ); strcat( strcpy( codefilename, fileprefix), "tab.c" ); headerfilename = MALLOC( size + 6, char ); strcat( strcpy( headerfilename, fileprefix), "tab.h" ); descfilename = MALLOC( size + 5, char ); strcat( strcpy( descfilename, fileprefix), ".out" ); actout = openw( codefilename ); defs( actout ); tokout = openw( headerfilename ); dump_header( tokout );
( https://github.com/open-watcom/open-watcom-v2/blob/master/bld/yacc/c/yacc.c )
Construct a string for environment:
env[0] = strcat(strcpy(env0, "TZ="), val);
( glibc/glibc-2.26/timezone/zdump.c )
Construct a string and pass it as an argument:
if( FileNameWild( argv[i], rxflag ) ) { dirp = NULL; } else if( IsSpecialRoot( argv[i] ) ) { dirp = opendir( strcat( strcpy( filebuff, argv[i] ), "\\" ) ); } else { dirp = opendir( argv[i] ); }
( https://github.com/open-watcom/open-watcom-v2/blob/master/bld/posix/src/ls/ls.c )
GetLine(rgb, strcat(strcpy(sbPrompt,GetMsg(P_defprompt)), " [nul.def]: "));
( WinNT-related-src/leaked-src/Win2K3/sdktools/link16/newcmd.c )
Construct a long buffer:
// FEXTRA *output_curpos++ = 3; // LSB *output_curpos++ = 0; // MSB output_curpos += 3; // 3 bytes of data // FNAME, null terminated filename output_curpos += strlen(strcpy(output_curpos, "my filename"))+1; // FCOMMENT, null terminated comment output_curpos += strlen(strcpy(output_curpos, "my comment"))+1;
( WinNT-related-src/leaked-src/XPSP1/inetsrv/iis/svcs/w3/filters/compress/gzip/gzip.c )
Construct a long string:
for (n = 0; n < 7; ++n) { pn->wday_abbr[n] = s; s += strlen(strcpy(s, pt->wday_abbr[n])) + 1; pn->wday[n] = s; s += strlen(strcpy(s, pt->wday[n])) + 1; } for (n = 0; n < 12; ++n) { pn->month_abbr[n] = s; s += strlen(strcpy(s, pt->month_abbr[n])) + 1; pn->month[n] = s; s += strlen(strcpy(s, pt->month[n])) + 1; }
( Win2K3/base/crts/crtw32/time/strftime.c )
Copy string and get its length at the same line:
rc = strlen(strncpy(outputString, "Unable to load msvcrt!__unDName", maxStringLength));
( WinNT-related-src/leaked-src/2000/private/sdktools/imagehlp/imagehlp.c )
Nested strcat/strcpy, pass the result to another function:
if (nameopt(strcat(strcat(strcpy(to, dir), "/"), from)) < 0) {
( QNX/trunk/utils/p/pax_qnx/pass.c )
Make copy of string and 'upper' it:
strupr( strcpy( node[i].fname, fname ) );
( https://github.com/open-watcom/open-watcom-v2/blob/master/bld/sdk/imgedit/c/ieopen.c )
Make copy of a string and do something with it:
slashify(strcpy(cmd, s), p);
( QNX/trunk/utils/g/gawk/pc/popen.c )
Allocate and copy buffer. This is the same as memdup() does:
PWSTR attrName = (PWSTR)memcpy(_alloca(len), newVal, len);
( WinNT-related-src/leaked-src/XPSP1/net/ias/providers/nap/cond/match.cpp )
/* * We mark any token, that that equals to a known enumerator, as * SYM_ENUM_CONST. The parser will change this for struct and union tags later, * the only problem is struct and union members: * enum e { a, b }; struct s { int a, b; } * but in this case, the only effect will be, that the ABI checksums become * more volatile, which is acceptable. Also, such collisions are quite rare, * so far it was only observed in include/linux/telephony.h. */ #define _APP(T,L) do { \ cur_node = next_node; \ next_node = xmalloc(sizeof(*next_node)); \ next_node->next = cur_node; \ cur_node->string = memcpy(xmalloc(L+1), T, L+1); \ cur_node->tag = \ find_symbol(cur_node->string, SYM_ENUM_CONST, 1)?\ SYM_ENUM_CONST : SYM_NORMAL ; \ cur_node->in_source_file = in_source_file; \ } while (0)
( https://github.com/torvalds/linux/blob/master/scripts/genksyms/lex.l )
Allocate and copy string. This is the same as strdup() does:
return strcpy(alloc(strlen(str)+1), str);
( id/quake3-1.32b/lcc/etc/lcc.c )
Allocate string, construct it and return it, in the same line:
return(strcpy(alloc((unsigned)(strlen(string)+1)),string));
( WinNT-related-src/leaked-src/Win2K3/sdktools/vi/alloc.c )
How memdup() and strdup() can be implemented?
#define smbestrdup(p) strcpy(malloc(strlen(p) + 1), p)
( plan9/extr/sys/src/cmd/aquarela/smbfns.h )
# define zstrdup( x ) strcpy( zmalloc( strlen(x)+1 ), x )
( WinNT-related-src/leaked-src/XPSP1/shell/osshell/accesory/ratpak/ratpak.h )
/* Clone an object P of size S, with error checking. There's no need for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any need for an arithmetic overflow check. */ void * xmemdup (void const *p, size_t s) { return memcpy (xmalloc (s), p, s); } /* Clone STRING. */ char * xstrdup (char const *string) { return xmemdup (string, strlen (string) + 1); }
( QNX/trunk/ports/tar/lib/xmalloc.c )
Comments at Reddit, at lobste.rs
Yes, I know about these lousy Disqus ads. Please use adblocker. I would consider to subscribe to 'pro' version of Disqus if the signal/noise ratio in comments would be good enough.