0

I have to scan a string with spaces so I can do somethings with it in this case moving the string n chars to the right or to the left. For example:

If I give n = 1, the string

house

becomes:

ehous

But the input can also be a string with spaces like, n being the same:

yellow house

becomes:

eyellow hous

So to scan the string im doing this:

char text[166];
scanf("%d %[^\n]%*c", &n, &text);

And everything works great, but now the I submitted the program I get this error:

src.c: In function 'main':
src.c:30:26: error: format '%[^
 ' expects argument of type 'char *', but argument 3 has type 'char (*)[166]' [-Werror=format=]
 30 |             scanf("%d %[^\n]%*c", &nVezes, &texto);
    |                       ~~~^~                ~~~~~~
    |                          |                 |
    |                          char *            char (*)[166]

What can I solve this? Also I can't use these libraries string.h, strings.h, and stdlib.h.

Every bit of help is appreciated.

  • 1
    `texto` is already a pointer (by virtue of array/pointer conversion), remove the `'&'` from the beginning in the `scanf()` parameter list. E.g. (use `texto` not `&texto`) – David C. Rankin Apr 11 '21 at 01:57
  • 2
    It is recommended you read your input with `fgets()` and then pass the filled buffer to `sscanf()` for parsing, e.g. `char buf[256]; if (fgets (buf, sizeof buf, stdin)) { if (sscanf (buf, "%d %165[^\n]%*c", &nVezes, texto) == 2) { /* you have valid conversions */ } }`. **Note:** you must include the *field-width* modifier any time you are reading strings to protect your array bounds. Otherwise, your use of `scanf()` is no safer than `gets()`. See [Why gets() is so dangerous it should never be used!](https://stackoverflow.com/q/1694036/3422102) – David C. Rankin Apr 11 '21 at 02:05
  • Perhaps mere pedantry, but string.h and stdlib.h are *not* libraries. A header is not a library, and a library is not a header. Understand the distinction before failing to recognize the distinction causes great confusion. – William Pursell Apr 11 '21 at 02:57

2 Answers2

1

scanf() does not truly scan a string but stdin.
Instead OP want to read a line of user input into an int and string.

Save headaches - ditch scanf() with its many weaknesses.

//         v---------------------- missing width limit
//                        v------- do not use here
scanf("%d %[^\n]%*c", &n, &text);
//     ^ ^ ----------------------- possible to read more than 1 line
// return value not checked

Use fgets() @David C. Rankin

char text[166];
char line[sizeof text + 20];
if (fgets(line, sizeof line, stdin)) {
  if (sscanf(line, "%d %165[^\n]", &n, text) == 2) {
    Success();  // OP's code here
  }
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

You don't need to pass the char array as a pointer(*). when you pass an array in C as an argument to a function, the name of the array acts as a pointer to the start of the array.

So, you should pass the array as follows:

scanf("%d %[^\n]%*c", &n, text);
Simon
  • 241
  • 2
  • 13
  • 2
    @JackLilhammers adding the `'s'` following `%[^\n]` is simply wrong. The `"%[..]"` conversion specifier is complete unto itself. Adding a trialing `'s'` would force `scanf()` to match a literal `'s'` in the input (which with `%[^\n]` would never match). – David C. Rankin Apr 11 '21 at 02:00
  • Further to @DavidC.Rankin adding a length constraint would be a good idea. Prevents overruns – Ed Heal Apr 11 '21 at 02:21
  • Thank you so much, since this was the simplier answer I tried it first and the problem was gone and the program passed! – Telmo Alexandre Apr 11 '21 at 12:51