1

I want to do the following, taking into account a string as how are you I want to print from a until e ie the word are. I tried this

char str[] = "how are you";
printf("%*.*s\n", 5, 8, str);

Output

how are

Expected output

are

Someone has idea how this can be done?

Kevin
  • 1,151
  • 1
  • 10
  • 18

3 Answers3

0

The characters in the string are indexed from 0, so the a is at index 4. By passing &str[4] to printf, the printf will start at the a, and print as many characters as specified by the precision.

printf("%.*s\n", 3, &str[4]);
user3386109
  • 34,287
  • 7
  • 49
  • 68
0

You are specifying field width and number of chars to print. However, the string always starts from the pointer as passed, there is no "start offset" specifier, as that would be unnecessary. See here for the format specifiers.

For your code, that would be printf("%.*s", width, str + start)

Note that &str[start] is identical.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • i.e `printf("%.*s", 3, str + 4);` I would prefer `strncpy` for this example though. I don't know why OP specifically wants it with `printf` – Imobilis Jun 14 '15 at 17:03
  • @Malina: Yes, in this case it would be width = 3, start = 4. I just prefer the general idea; might avoid further questions ("how do I print 5 chars from ...). Possibly because `strncpy` would have a hard job getting the string to `stdout`? If you just refer to taking the substring: because that is well defined and does avoid copying with all implications (buffer required with possibly unknown size, costly block transfer)? – too honest for this site Jun 14 '15 at 17:15
  • I mean `stdncpy` to build a string with exactly the same width and print it with `puts` (if the newline isn't a problem). Surprised or not, my test reveals that this is exactly 3 times faster. And probably less error-prone. I am not a master of the variadic function `printf` as I don't know its implementation. But 3 times faster in a loop of 10 iterations.. – Imobilis Jun 14 '15 at 17:54
  • @Malina: I got what you mean, that's what my "If you just ..." par is about. And that still hold true. Speed is the leaast to worry about a function which is meant to show up to the user (unlikely that it is to be redirected), here readable code is more important. However, you might have a pretty bad implementation of `printf()`. No wonder, as the string functions are often higly optimized and inlined. So, what's left? - Memory allocation. The target array required has to be either local (with max. possible size: critical for a stack-allocated variable), or allocated dynamically (size=strlen?) – too honest for this site Jun 14 '15 at 19:05
  • @Malina: Even more, OP asked about that particular functionality, not strncpy, malloc(), etc. – too honest for this site Jun 14 '15 at 19:06
  • I know. And I commented. And it was "I wonder why" - a question I've asked myself.. (or whoever wants to answer). And you did.. but I have to say it again. It is faster. Which is why I would prefer it. The ""easier"" way has no other benefits other than that it is "easy". Static array, located on the stack will be accessed really quick. `static char substr [3]; memcpy(substr, &str[4], 3); puts(substr);` From now on it is up to OP to decide which one to use. – Imobilis Jun 14 '15 at 19:36
  • @Malina: It is not _faster_ per se, as it depends on the implementation of your stdlib. Any other implementation might have very well the cards shuffled differently. Trading of explicitly and easy to mainatin vs. speed is poor design most times. And you forget the OP has likely just shown an example, so the length might very well be 100 chars for instance. And then not only memory, but also speed will look very different. Never use a special solution where a more general is cleaner and sufficient. Fundamentals of programming. Your attitude results in assembler if followed consequently. – too honest for this site Jun 14 '15 at 19:59
  • glaringly but if it comes to speed premature optimization (aka sonic) I would use neither. If the case corresponds to the example I would use: `int* substr = (int*)&str[4]; ((char*)substr)[3] = '\0'; puts((char*)substr);` lol And no, it is all-safe. – Imobilis Jun 14 '15 at 20:43
  • Invoking UB for nonsense? Modifying the original string? You have no knowledge what side-effects that will have. If the original string is `const`, you invoke UB with that. Not, thank you. Sorry, but you always fall into common pits, and I am not here to tutor you. – too honest for this site Jun 14 '15 at 21:14
  • I don't need too. This doesn't invoke UB LOL. The behavior of this is pretty well-defined. – Imobilis Jun 14 '15 at 21:19
  • Writing to a `const` is well defined? Good joke! That leads nowhere (again). Learn about correct programming. You would fail any course here. – too honest for this site Jun 14 '15 at 21:22
  • What is declared as const?? Nothing from what I exemplified is `const` ! Nope. I didn't fail any course. You are just very very bad in understanding my point.. especially if I apply a little bit abstraction and/or imagination. Which is a great thing in programming. Who said the string has to be `const` ? – Imobilis Jun 14 '15 at 21:24
  • If the `str` is defined as `const` then yes. It is UB by any meaning.. When I was providing this way.. I considered str a regular string, in non-read-only memory area. Obviously. – Imobilis Jun 14 '15 at 21:26
0

try using this code

printf("%.*s\n", 3, &str[4]);
jcoppens
  • 5,306
  • 6
  • 27
  • 47