0
char text[10];
printf("Enter text[Max characters= 9]: ");
scanf("%[^\n]s",&text);

I wrote this by mistake and kept working with it, later on I noticed the mistake in scanf but my question is why was there no error? 3rd line means save the string at the address of address of first element of the array, correct?

P4Penguin
  • 23
  • 3
  • 1
    You should be getting a warning, and you should always fix all warnings. See [this question](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings) for more. – user3386109 May 20 '22 at 02:47
  • Behaving as you expect is just one of the infinitely many possible consequences of undefined behavior (and perhaps the worst, since it means it's hard to find the problem). – Keith Thompson May 20 '22 at 04:13
  • You my want to read this: [What is array to pointer decay?](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay) – Andreas Wenzel May 20 '22 at 04:22
  • ....because C is irrational when it comes to array arguments? :) – Martin James May 20 '22 at 04:52

1 Answers1

2

Your a.c source code

#include <stdio.h>
int main()
{
    char text[10];
    printf("%p\n", text);
    printf("%p\n", &text);
    printf("Enter text[Max characters= 9]: ");
    scanf("%[^\n]s",&text);
    printf("%p\n", text);
    printf("%p\n", &text);
    return 0;
}

As you can see on the following logs

bash-5.1$ gcc a.c -o a
bash-5.1$ ./a
0x7fff602b2166
0x7fff602b2166
Enter text[Max characters= 9]: afaefa
0x7fff602b2166
0x7fff602b2166

Text and &text points to the same address. &text on a scanf doesn't break your code but its redundant.

But if you compile with -Wall flag

bash-5.1$ gcc a.c -o a -Wall
a.c: In function ‘main’:
a.c:8:15: warning: format ‘%[^
   ’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[10]’ [-Wformat=]
    8 |     scanf("%[^\n]s",&text);
      |            ~~~^~    ~~~~~
      |               |     |
      |               |     char (*)[10]
      |               char *
Gabriel Pellegrino
  • 1,042
  • 1
  • 8
  • 17
  • 1
    To be correct, you need to cast the pointers in `printf` to `(void*)`. – Gerhardh May 20 '22 at 04:49
  • 1
    You can (and should) enforce the limit with `"%9[^\n]"`. Also note that the `s` after the scan set will only match a literal `s` in the input string — the scan set conversion specifier `%[…]` is complete at the `]`. – Jonathan Leffler May 20 '22 at 05:29