0
void Init() {
    fflush(stdin);
    printf("Input the cup name:");

    scanf("%[^\n]s", array_of_water[indexx].name); 
    array_of_water[indexx].water = rand() % 31 + 20;
}

"%[^\n]s" I know it will read the string until it encounters newline. But, How to make exception for the first char to be not newline.

If I press enter on my keyboard the string will save \n as its element. But I don't want that, I want to let user enter except for newline itself. Besides that, how the format specifiers change if I want read until encounter alphabet/number/other symbols?

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Andrew530
  • 1
  • 2
  • 2
    First of all passing an input-only stream (like `stdin`) is explicitly mentioned in the C specification as leading to *undefined behavior*. One compiler and standard library have added it as a non-portable and very non-standard extension. Don't use it. It's not even needed first thing in your program, as the input buffer will be empty anyway. – Some programmer dude Dec 09 '22 at 13:32
  • 4
    Secondly, I really recommend you kind of forget that `scanf` exists for input. To read a full line use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets). – Some programmer dude Dec 09 '22 at 13:32
  • 1
    `"%[^\n]"` without a _width_ is worse than [`gets()`](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used). – chux - Reinstate Monica Dec 09 '22 at 16:01
  • "If I press enter on my keyboard the string will save "\n" as its element." --> No. that did not happen. Also please report the return value of `scanf()`. – chux - Reinstate Monica Dec 09 '22 at 16:03
  • Andrew530, Who or what text suggested an `s` in `"%[^\n]s"`? – chux - Reinstate Monica Dec 09 '22 at 16:04
  • 1
    @Some programmer dude [comment](https://stackoverflow.com/questions/74743770/how-to-read-a-string-until-new-line-except-for-the-first-char-is-newline-itself#comment131915572_74743770) missing `fflush()`. As is the comment is unclear. – chux - Reinstate Monica Dec 09 '22 at 16:05
  • @chux-ReinstateMonica Oh yeah, seems I left out quite an important bit. Yes the comment is about `fflush` and passing `stdin` to it. – Some programmer dude Dec 09 '22 at 16:12

1 Answers1

2

How to read a string until new line except for the first char is newline itself ...?

Correct use of scanf() will succeed

OP's scanf("%[^\n]s", array_of_water[indexx].name); lacks context as the size of array_of_water[indexx].name is unknown, as well as the input. fflush(stdin); is also undefined behavior. Delete it.

The s in "%[^\n]s" is amiss.

Drop the s.

char buf[100];
int count = scanf("%99[^\n]", buf);
switch (count) {
  case EOF: puts("End of file or input error"); break;
  case   1: printf("Success <%s>\n", buf); break;
  case   0: puts("Nothing read"); break;
}

Left to do:

  • Consume rest of non-'\n' line if length of buf was 99.

  • Consume final '\n'.

  • Handle pesky null characters, if they were read.


Easier to just use fgets().

char buf[100];
if (fgets(buf, sizeof buf, stdin)) {
  buf[strcspn(buf, "\n")] = 0; // Lop off potential \n
  printf("Success <%s>\n", buf);
} else {
  case EOF: puts("End of file or input error"); break;
}

Left to do:

  • Maybe consume rest of non-'\n' line if length of buf read was 99.
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Note that used with the same buffer length, `scanf("%99[^\n]", buf)` and `fgets(buf, sizeof buf, stdin)` behave the same only if 99 or more bytes have been read from `stdin` without any newline. If fewer bytes are available, the newline if consumed and stored into the target array by `fgets()` but left in the input stream by `scanf()`. – chqrlie Dec 09 '22 at 20:06
  • @Also: `scanf()` fails, does not modify the target array and returns `0` if a newline is read from `stdin` immediately whereas `fgets()` happily reads an empty line consisting of a single `\n` byte. – chqrlie Dec 09 '22 at 20:07