0

I'm trying to get user input for my string with spaces on my program but for some reason %[^\n] doesn't work.

The % part is marked red. I couldn't understand why. It just skips and doesn't ask for user input.

int prelim, midterm, semiFinal, final, totalScore, yearLevel, studentId;
float averageScore = 0;
char name[25], degree[25];

printf("Enter your student id: ");
scanf("%d", &studentId);
printf("Name: ");
scanf("%[^\n]s", &name);
printf("Degree: ");
scanf("%[^\n]s", &degree);
printf("Year: ");
scanf("%d", &yearLevel);
user438383
  • 5,716
  • 8
  • 28
  • 43
  • In this format string `%[^\n]s` the `'s'` is not part of the format specifier but an extra character. Did you mean `%[^\n]` instead? – Gerhardh Sep 16 '21 at 08:18
  • 1
    To avoid potential problems with buffering, you should add `\n` to your `printf` to trigger flushing of `stdout` before reading. Otherwise you might not see any output when you are waiting for input. Also you should not add `&` to array names. They automatically decay to a pointer when passed to a function. – Gerhardh Sep 16 '21 at 08:20
  • 1
    Common newbie error: `%s` and `%[...]` are quite different format specifiers. The second is not a subset of the first. You also need a space before `%` to filter the previous newline left in the buffer, to limit the input length, and remove the `&`. So `scanf(" %24[^\n]", name);`. Ditto for `degree`. I recommend you spend at least one hour studying `scanf` in detail, using hands-on examples/tests. There is a great deal to take in, and its behaviour varies with each format specifier. – Weather Vane Sep 16 '21 at 08:21
  • It worked now. I see where I made my mistake. Thank you all very much. I'm going to study a lot more. I just got into programming and this is really fun. – NemuriNemuri Sep 16 '21 at 08:34
  • I'm going to offer a dissenting opinion to @WeatherVane's recommendation to spend time studying `scanf` in detail. In the long run, `scanf` is useless. Any time you spend studying it is time you're not spending learning how to [use something better](https://stackoverflow.com/questions/58403537). And you really want to learn something better, and wean yourself entirely off of `scanf` as soon as you are comfortable. – Steve Summit Sep 16 '21 at 20:51

1 Answers1

1

First of all, scanf("%[^\n]s", &name) must be scanf("%[^\n]", name) as

  1. The s is not part of the %[ format specifier as people new to C often think.
  2. The ampersand should be removed as the name of an array decays to a pointer to its first element which is already the type that %[ expects.

Now, to answer your question, %[^\n] will fail if the first character it sees is a \n. For the scanf for studentId, you type the number and press Enter. That scanf consumes the number but leaves the enter character (\n) in the input stream. Then, the scanf for name sees the newline character and since it's the first character that it sees, it fails without touching name. The next scanf fails for the same reason and the last scanf waits for a number.

But wait! Why doesn't the last scanf fail as well? The answer to that is certain format specifiers like %d skip leading whitespace characters. The %[ format specifier does not.

Now how do we fix this? One easy solution would be to tell scanf to skip whitespace characters before the %[ format specifier. You can do this by adding a space before it: scanf(" %[^\n]", name). When scanf sees the space, it will skip all whitespace characters from the input stream until the first non-whitespace character. This should solve your problem.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83