concat.cpp

(plain text)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <vector>

//####################################################################
//! Similar to strncpy(dest, src, len) except that the sequence will
//! always be null-terminated.
inline char *safe_strcpy (char *dest, const char *src, size_t len) {
  assert(len > 0);
  strncpy(dest, src, len - 1)[len - 1] = '\0';
  return dest;
}
//####################################################################
//! Similar to strncat(dest, src, len) except that the length is of
//! the size of dest, not the maximum number of bytes to write.
inline char *safe_strcat (char *dest, const char *src, size_t len) {
  assert(len > 0);
  size_t off = strlen(dest);
  strncpy(dest + off, src, len - off - 1)[len - off - 1] = '\0';
  return dest;
}

int main () {
  const char hello[] = "hello", world[] = " world";

  /* C: big-buffer (make sure it's big enough!) */
  char buf[80];
  puts(strcat(strcpy(buf, hello), world));

  /* C: safe big-buffer */
  puts(safe_strcat(safe_strcpy(buf, hello, sizeof(buf)), world, sizeof(buf)));

  /* C: dynamic allocation */
  char *p = (char *)malloc(strlen(hello) + strlen(world) + 1);
  if (p != 0) puts(strcat(strcpy(p, hello), world));
  free(p);

  // C++: manual dynamic allocation with std::vector (preferred over new[])
  std::vector<char> v(strlen(hello) + strlen(world) + 1);
  std::cout << strcat(strcpy(&v[0], hello), world) << '\n';

  // C++: automatic dynamic allocation with std::string (preferred overall)
  std::string s;
  std::cout << s.assign(hello).append(world) << '\n';

  return 0;
}