To print only five characters from a string:
printf("The first five characters are %.5s\n", the_string);
There's no need to copy the string to do that. (Note the difference between the format %.5s
, which is "if the string argument is longer than five characters, use only the first five.", and %5s
, which is "if the string is shorter than five characters, first output enough spaces to make the total width five." These two options are independent of each other,, so you can use both: %7.5s
would be "use at most five characters, and place them at the right-hand side of a seven-character field. If you want to pad on the right instead of the left, use a minus sign.)
In fact, there is much less need to copy strings than you might think. Unnecessary copying is time-consuming and error-prone. It is also surprisingly common. So you should always ask yourself if a copy is really necessary.
If you decide that a copy really is necessary, your first point of call is strndup
, which dynamically allocates exactly enough storage for a substring of a specified size:
char* strndup(const char* original, size_t n);
That lets you do things like:
char* first_five = strndup(the_string, 5);
(If the_string
only has three characters, for example, that's not a problem. You'll get all three of them.)
Or, if you want a substring from the middle of the string:
char* substring = strndup(the_string + start, length);
This is not quite as safe, since there is no way that strndup
can verify that the_string
has at least start
characters. To make it safer, you could do this:
char* substring = strndup(the_string + strnlen(the_string, start), length);
If you really really know that start
is in range, you don't have to do that. Counting the first start
characters, which is what strnlen
does, is not very efficient. But it's better than counting all the characters, which is what strlen
does.
(If you think the_string + start
looks odd, remember that it is exactly the same as &the_string[start]
; that is, it is the address of element start
in the array the_string
.)
You should always use strndup
if possible, because it's the only moderately standard function which is (reasonably) safe. It's (reasonably) safe because it doesn't depend on your knowing that the destination string is big enough. Unfortunately, it (and strnlen
) are not yet part of thne C standard (although they're coming soon, I believe), and they were only added to Posix in the 2008 revision. But they've been available for a long time on Linux and for several years now on Mac OS X.
You will need to use the correct feature-test macro, though:
#define _POSIX_C_SOURCE 200809L
or
#define _XOPEN_SOURCE 700
That has to go before any #include
in the file which uses the function. If you're using clang or gcc, you can add a -D
option to your compile command.
If you need Windows compatibility, you'll have to find an open source implementation; fortunately, that's not too hard: