2

execution function:

printf("%s\n", "123456789" + 3); //output: "456789"

why output this result? In the same way, what should I do if I want to output "123"? Now I'm confused. Help me.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 1
    Try `printf("%d\n", 123456789 + 3);` – Déjà vu Apr 18 '19 at 02:47
  • I want to use this feature to split strings. – user11376714 Apr 18 '19 at 02:50
  • 2
    You are getting bit by c's [pointer arithmetic](https://stackoverflow.com/questions/394767/pointer-arithmetic). – Ray Tayek Apr 18 '19 at 02:51
  • Splitting strings in C is not a trivial procedure like it is in many other languages. This is partly because C uses null-terminators as opposed to a length to determine how long a string is. To split a string, you need to allocate memory, copy part of the string to the new string, then truncate your original string. – kruschk Apr 18 '19 at 02:55
  • 3
    "what should I do if I want to output "123"?" --> `printf("%.3s\n", "123456789");` – chux - Reinstate Monica Apr 18 '19 at 02:58
  • @user11376714 *I want to use this feature to split strings.* -- Choose a language, either C or C++. This is becoming an [XY problem](http://xyproblem.info/) – PaulMcKenzie Apr 18 '19 at 03:01
  • Your sample code does not split strings. It just ignores a few characters but they are still there in same place. – Gerhardh Apr 18 '19 at 05:46

4 Answers4

7

printf() is passed a pointer to a string constant incremented by 3

printf("%s\n", "123456789" + 3);  

printf() takes a format string argument followed by a variadic set of arguments. In this case, the '%s' is the first (and only) variable in the format string.

There is only one argument in the variadic section after the format string: a string constant: "12345678" which resolves to a pointer to the '1' character; however, that pointer is incremented by 3 due to the "+ 3". This moves the pointer 3 positions to the '4'.

Then, printf prints the string that starts at '4'. As the string constant is terminated by a '\0' character right after the '9', printf prints "456789"

Printing the first 3 chars of a string To print only the first 3 characters of a sting, use %.3s in the printf format string:

printf("%.3s\n", "123456789");
Gardener
  • 2,591
  • 1
  • 13
  • 22
  • 1
    Thank you, @RingØ, once I read the first part of the question, I forgot to answer the second part. I have edited the answer to provide the method to print 3 characters from a string without printing the entire string. `printf("%.3s\n", "123456789");` – Gardener Apr 18 '19 at 04:58
  • 1
    Thank you for solving my problem. – user11376714 Apr 18 '19 at 08:37
1

Basically, strings are character arrays, meaning their name (variable name) points to the first element in the array. For instance, in the array a[]={3, 4, 5}, a[0] is obviously 3. However, the value of a itself is also 3 (like printf("%d", *a);) If you increment a itself, you are incrementing the address of a, so the value of a + 1 would be 4. Implicitly declaring a character array (what you did with the string) still requires the program to give it some form of address (That is, the location where the 1 in "123456789" is located) That being said, incrementing the string itself basically acts the same as incrementing the array name, so "123456789" + 3 would give the address associated with "456789". So what the printf basically sees is "print 456789".

I doubt I was able to explain this as simply as possible, or if you could even follow this, but I tried.

Best of luck!

Flacarile
  • 69
  • 5
  • Nope, the value of `a` itself is a pointer to the first element, not the value pointed to, so you have to dereference it (as you do with the `*` in front of `a`) The value of `a` itself is not `3` as you post in your answer. Please, edit your answer and add a comment mentioning me, and I'll take this comment off of the view. Thanks. – Luis Colorado May 17 '19 at 18:57
1

One just can't add a string ("123456789") and a number (3). What is it that you want? a) Integer addition or string concatenation?

a) 123456789 + 3
b) "123456789" + "3"

The compiler will not guess which option do you want! So, one of the arguments needs to be converted to the type of the other, using some function such as (unsafe) atoi(), etc...

Luis Dipak
  • 71
  • 3
1

"123456789" is a string literal. It is an object of type char [10] in C. It is an object of array type.

When an object of array type is used with binary + operator, it gets implicitly converted (decays) to pointer type. The resultant pointer value points to the beginning of the array. So, the original char [10] array decays to char * pointing to character '1' in "123456789".

Binary operator +, when applied to a pointer, performs pointer arithmetic. Adding 3 to a char * pointer produces a pointer that points 3 bytes to the right of the original pointer. So, you get a pointer that points to character '4' in "123456789".

After that you use format %s to ask ask printf to print a string that begins from that '4'. And that is the output you get.


The same thing happens in C++, except that in C++ this string literal has const char [10] type and decays to const char * pointer,

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765