#include <iostream>
#include <cstring> // assuming these are dumped to the global namespace
int main() {
char a[] = "200708201425";
char b[16] {}; // important to zero it out since
// strncpy doesn't add terminating '\0'
// and strcat needs the '\0'.
strncpy(b, a + 4, 2);
strcat(b, "/");
strncpy(b + 3, a + 6, 2);
strcat(b, "/");
strncpy(b + 6, a, 4);
strcat(b, " ");
strcpy(b + 11, a + 8);
std::cout << b << '\n'; // 08/20/2007 1425
}
Alternatively, and assuming you want a ':' in the time value, too:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <cstring>
int main() {
char a[] = "200708201425";
char b[20];
strncpy(b, a + 4, 2);
b[2] = '/';
strncpy(b + 3, a + 6, 2);
b[5] = '/';
strncpy(b + 6, a, 4);
b[10] = ' ';
strncpy(b + 11, a + 8, 2);
b[13] = ':';
strcpy(b + 14, a + 10); // strcpy to zero-terminate
std::cout << b << '\n'; // 08/20/2007 14:25
}
Very nice also! That's both occurrences of strlen gone.
Do you know any way to initialise b directly with base and avoid the strcpy too? The obvious didn't work because of the const-ness of base or decay to a pointer.
Do you know any way to initialise b directly with base
No, like you say it's basically a pointer, so you need to use strcpy to copy what it points to. In fact base may as well just be constchar* base since making it constchar base[] actually creates a char array of the appropriate size and copies the string literal into it. So that's a way to avoid one copy, although one that only happens on initialization.
It depends on exactly how it's used in the actual program, but for this case you don't really need base. It just gives the initial string a name, which may or may not be useful in general.
And it is possible to copy the string without strcpy but it requires wrapping it in a struct:
1 2 3 4 5 6 7
struct Base {
staticchar b[];
} base;
char Base::b[] = "--/--/---- ----";
// ...
Base b{ base };
But surely that's overkill just to avoid strcpy!
And it ruins the clean simplicity of the original code.