Fraser Langton
Fraser Langton

Reputation: 661

How to exit a scanf loop with newline character. Currently loops indefinitely

I am trying to get: while(scanf("%c %c %d\n", &a, &b, &c) && (a!='\n')) to exit once a line is blank, eg the following:

a b 12
q w 4
g u 80

(exit)

Code:

while(scanf("%c %c %d\n", &a, &b, &c) && (a != '\n'))

Upvotes: 1

Views: 919

Answers (1)

chux
chux

Reputation: 153478

To read a line, use fgets(). Then, if successful, parse the input string for '\n', expected a,b,c, or anything else.

//                          c  ' '  c  ' '  d   \n  \0
#define LINE_EXPECTED_SIZE (1 + 1 + 1 + 1 + 11 + 1 + 1)

char buf[LINE_EXPECTED_SIZE * 2]; // let us be generous with size.
while (fgets(buf, sizeof buf, stdin) && buf[0] != '\n') {
  char a,b;
  int c;
  if (sscanf(buf, "%c %c %d", &a, &b, &c) != 3) {
    // Note unexpected input
    fprintf(stderr, "Unexpected bad input '%s'\n", buf);
    break;
  }
  printf("a:'%c', b:'%c', c%d\n", a,b,c);
}

"\n" is rarely correct at the end of a scan() format. @Jonathan Leffler.


The above uses sscanf(...) != 3 to detect if 3 specifiers were matched. This will not detect if extra text was on the line. An advanced approach uses " %n" to scan optional following white-space and then note the scan offset at that point.

  // if (sscanf(buf, "%c %c %d", &a, &b, &c) != 3) {
  int n = 0;
  sscanf(buf, "%c %c %d %n", &a, &b, &c, &n);
  if (n == 0 || buf[n] != '\0') {
    // if scanning did not reach %n or extra text followed ...

Upvotes: 3

Related Questions