0

I have this simple code in C to scan and print a string with a whitespace:

#include <stdio.h>
#include <string.h>
int main()
{
   char myName[50];
   printf("Enter your name: ");
   scanf("%[^\n]s", &myName);
   printf("Your name is: %s", myName);
   return 0;
}

The compiler (gcc, part of the command line tools that come with Xcode on my mac) is returning this error:

name.c: In function ‘main’:
name.c:7: warning: format ‘%[^
’ expects type ‘char *’, but argument 2 has type ‘char (*)[50]’
name.c:7: warning: format ‘%[^
’ expects type ‘char *’, but argument 2 has type ‘char (*)[50]’

What's the problem here?

NOTE: I am required to use scanf. No fgets for me :(

5 Answers5

4

You should pass to scanf argument of type char* (format %[^\n]s expects so), but in your code:

char myName[50];
scanf("%[^\n]s", &myName);

you pass an address of myName array (i.e. char (*)[50]). You should change it either to:

scanf("%[^\n]", myName);

or:

scanf("%[^\n]", &myName[0]);
LihO
  • 37,789
  • 9
  • 89
  • 156
  • 1
    Recommend dropping the `s` in `"%[^\n]s"` as it is not needed. Leaving it there implies it is somehow useful. – chux - Reinstate Monica Sep 27 '13 at 20:44
  • 1
    OP's question is "Problems with scanf on strings with _spaces_". Using the `%[]` specifier is used to read strings with _spaces_. I fully agree that the `&` issue is central to the OP's problem. But incorrect usage of the format specifier (unneeded `s`) certainly is a related problem given the OP's title. – chux - Reinstate Monica Sep 27 '13 at 22:10
2

Couple issues

  1. Wrong scanf() format s. The s is not part of the format specifier. The %[] format specifier ends with the ].

  2. Wrong scanf() parameter &myName. Rather than passing the address of &myName, which is type char (*)[50] , simply use myName. This will pass the address of the first element of myName which is a char *, the expected matching type for %[].

Use

scanf("%[^\n]", myName);

Further recommend to consume leading white space and limit text read. The 49 limits the input to 49 characters, leaving 1 more byte for the terminating \0.

scanf(" %49[^\n]", myName);
chux - Reinstate Monica
  • 113,725
  • 11
  • 107
  • 213
  • I get same results with either `"%49[^\n]s"` or `"%[^\n]s"`. What exactly is this supposed to do? – ryyker Sep 27 '13 at 20:36
  • @ryyker The `49` limits the amount of text read to 49 `char`. Had you type in a long name, `myName` would overfill thus invoking undefined behavior. BTW, you do not need the `s`. – chux - Reinstate Monica Sep 27 '13 at 20:47
2

What's the problem here?

Well, here it is:

format expects type ‘char *’, but argument has type ‘char (*)[50]’

A pointer to an array is not the same as a pointer to the first element of an array. You should get rid of that & operator.

1

In C, myName (when passed to a function) decays to a pointer to the first element of array (myname) of characters. &myName is a pointer to the array myname. &myName[0] would be a pointer to the first character, which is correct, but looks like you tried stuff at random until you chanced on something that worked.

haccks
  • 97,141
  • 23
  • 153
  • 244
  • 1
    No, `myName` is an array, which decays into a pointer. `&myName` is not a pointer to pointer, it's a pointer to an array. –  Sep 27 '13 at 20:18
  • 1
    Same difference. He needs to delete the ampersand. – 15ee8f99-57ff-4f92-890c-b56153 Sep 27 '13 at 20:20
  • If he types myName there, he's passing the pointer. Yes, technically, I should use the word "decay". Or "treated as", or something. OK. Next time I will (if I remember, which at this late stage of my career, I promise you I won't). But it'll compile and work and his understanding will be correct for all practical purposes if he thinks of myName as a pointer when he passes it, because a pointer will be what he is passing when he does that. "Incorrect", whatever. – 15ee8f99-57ff-4f92-890c-b56153 Sep 27 '13 at 20:20
  • Well, you definitely can. Write "array" instead of "pointer" and it will be correct. –  Sep 27 '13 at 20:21
  • Calling `myName` a pointer is problematic when explaining `sizeof`. Many posts reflect that challenge. – chux - Reinstate Monica Sep 27 '13 at 20:30
0

Your problem is that your are passing the address to the pointer of the start of the string, rather than the pointer to the string. Simply, remove the &.

   scanf("%[^\n]", myName);
Freddie
  • 833
  • 6
  • 10
  • Also the `s` does not make sense here. `%[^\n]` already asks for all characters but a new-line. – alk Nov 25 '18 at 18:59