91

Say I have the following:

char* string = "Hello, how are you?";

Is it possible to print out only the last 5 bytes of this string? What about the first 5 bytes only? Is there some variation of printf that would allow for this?

Matthew Slattery
  • 45,290
  • 8
  • 103
  • 119
Tim
  • 4,295
  • 9
  • 37
  • 49

3 Answers3

155

Is it possible to print out only the last 5 bytes of this string?

Yes, just pass a pointer to the fifth-to-the-last character. You can determine this by string + strlen(string) - 5.

What about the first 5 bytes only?

Use a precision specifier: %.5s

#include <stdio.h>
#include <string.h>
char* string = "Hello, how are you?";

int main() {
  /* print  at most the first five characters (safe to use on short strings) */
  printf("(%.5s)\n", string);

  /* print last five characters (dangerous on short strings) */
  printf("(%s)\n", string + strlen(string) - 5);

  int n = 3;
  /* print at most first three characters (safe) */
  printf("(%.*s)\n", n, string);

  /* print last three characters (dangerous on short strings) */
  printf("(%s)\n", string + strlen(string) - n);
  return 0;
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • @Tim - You are welcome. Don't forget to upvote all the useful answers, and accept the answer that solved your problem. (P.s. Heed the advice in the other post -- if your string is too short, then this code will fail.) – Robᵩ Oct 15 '11 at 21:51
  • Updated sample program to address @Tim's comments in other answer. – Robᵩ Oct 15 '11 at 22:38
  • 1
    Note that `printf` will still stop at the first null character. – Flimm Apr 29 '14 at 16:59
  • 1
    Amazing answer. I knew there could be done a lot, but this still surprised me. Thank you very much. – Anton Krug Feb 07 '18 at 14:42
23

Yes, the last five bytes of that string can be done with:

printf ("%s\n", &(string[strlen (string) - 5]));

The first five can be done with:

printf ("%.5s\n", string);

You can combine the two to get substrings within the string as well. The word how can be printed with:

printf ("%.3s\n", &(string[strlen (string) + 7]));

You do have to be careful that the string is long enough for this to work. Printing the last five characters of a one-character string will cause undefined behaviour since the index ends up at -4. In other words, check the string length before attempting this.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 2
    Thank you, very informative. Is it possible to print out the first n bytes of a string, if you don't know what n is at compile time? Say n was an int, could I just have printf("%ns", string); ? Also, why is it "5.5" instead of just "5" in your "printf ("%5.5s\n", string);" (and similarly, 3.3 in the other one)? – Tim Oct 15 '11 at 22:02
  • 5
    Tim: yes. Check out the %*s format specifier. Basically you supply an int just before the string, that specifies the width of the string. – Jörgen Sigvardsson Oct 15 '11 at 22:08
  • 1
    @Tim: yes, Jörgen has already stated how to use something like `int x = 3; printf ("%.*s, x, "abcde")`. As to the _two_ numbers, that's not really necessary in this case since you know you have enough characters but I still do it from force of habit. For strings, it's effectively the minimum and maximum lengths. I'll take it out since it's superfluous here. – paxdiablo Oct 15 '11 at 22:13
  • 1
    @JörgenSigvardsson: I think you meant the `%.*s` format specifier, not the `%*s` format specifier. – Flimm Apr 29 '14 at 16:51
  • Note that `printf` will still stop at the first null character. – Flimm Apr 29 '14 at 16:59
  • @Flimm: Admittedly, I've been working on Windows for quite some time now, so it's possible I've used an old Microsoft-ism. – Jörgen Sigvardsson Apr 30 '14 at 08:25
-1

Two solutions:

Say given a predicatable string with same length - I will use date as an example and asked to split into HH:MM:SS.DDDDDDD

char date[14] = "2359591234567";

[1] Readable Implementation:

char hh[3] = {0};
char mm[3] = {0};
char ss[3] = {0};
char dec[8] = {0};
strncpy ( hh, date, 2 );
strncpy ( mm, date+2, 2 );
strncpy ( ss, date+4, 2 );
strncpy ( dec, date+6, 7 );

printf("%s:%s:%s.%s\n", hh, mm, ss, dec);

[2] Short Implementation:

Either:

printf("%.2s:%.2s:%.2s.%.7s\n", date, date+2, date+4, date+6);

or:

printf("%2.2s:%2.2s:%2.2s.%7.7s\n", date, date+2, date+4, date+6);

Should work.

Instead of printf - you can use sprintf and copy to a buffer. I would also check for the correct length to avoid unpredictable behavior.

In either case - the output will be:

23:59:59.1234567
Kapil Vyas
  • 607
  • 2
  • 8
  • 22