3

I am trying to take string input in an infinite while loop that saves the string in the same array every time, but I wish this loop to terminate when I press Enter

The code looks something like this:

int main()
{
    char input[1000];
    while (1)
    {
        scanf("%s",input);
        if (input[0] == '\n'){ break; } //the problem is that scanf never gets the \n
        else{...}
    }
    return 0;
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
xixhxix
  • 153
  • 1
  • 1
  • 12

6 Answers6

5

A newline, \n, is considered a white-space character.

If you read the C11 spec, chapter §7.21.6.2 you can see, regarding the %s format specifier with scanf() family

s

Matches a sequence of non-white-space characters.

So, using a scanf() call with %s, you cannot intake a (only) \n, which is indeed a white-space charterer.

You need to use getc() to read a newline.

Alternatively, you can use fgets() which actually reads and stores the trailing newline.

FWIW, int main() should better be int main(void), at least.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 3
    Any reason for the _wholesale_ downvote, dear downvoter? – Sourav Ghosh Nov 16 '15 at 16:27
  • is there a way to see what is the first character in the buffer without getting it out of there? – xixhxix Nov 16 '15 at 16:30
  • @xixhxix: That's a separate question, and I'll bet you can find one already. But the answer is `getc` followed by `ungetc`. See `man getc`. (To save you the trouble of searching *this time*, here's the already-asked question: http://stackoverflow.com/q/13993742/1566221) – rici Nov 16 '15 at 16:48
2

Edit: You can tell scanf() to accept specific char with scanf("%[a-zA-Z0-9 ]", ...);

2

The conversion "%c" matches any character including whitespace. If you really need to use scanf(), use it with that.

// you can put this in a loop
char ch;
if (scanf("%c", &ch) != 1) /* error */;
printf("the character read is '%c' and has value %d\n", ch, ch);

Note that solutions using other functions (getc(), fgets()) are way better.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • The OP still requires to read the string when the input is not only a `/n`, maybe `scanf("%20[^\n]%c", buff, &c);` would solve it by storing the `/n` in `c` – PeCosta Nov 16 '15 at 16:30
  • @PeCosta `scanf("%20[^\n]%c", buff, &c);` does not work when the first `char` is `'\n'`. This seems to be a case OP is looking for with code `if (input[0] == '\n')`. – chux - Reinstate Monica Nov 16 '15 at 17:51
1

Instead, use fgets() to read the line and strcspn() to lop off the potential trailing '\n'

int main(void) {
  char input[1000];
  while (fgets(input, sizeof input, stdin)) {
    input[strcspn(input, "\n")] = '\0';
    if (input[0] == '\0') { 
      break;
    } else { 
      ; // ...
    }
  }
return 0;
}

or don't lop off the '\n' @R Sahu

int main(void) {
  char input[1000];
  while (fgets(input, sizeof input, stdin)) {
    if (input[0] == '\n') { 
      break;
    } else { 
      ; // ...
    }
  }
return 0;
}
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Use fgets(input, 1000, stdin) instead.

Then use size_t s = strlen(input); and, if the returned length is adequate, look at input[s - 1] which will be the newline character, which you can test with input[s - 1] == '\n'.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0

Instead of using scanf, using fgets.

while (1)
{
    if ( fgets(input, sizeof(input), stdin) == NULL )
    {
       // Error reading. Perhaps EOF is reached.
       break; //???
    }

    if (input[0] == '\n'){ break; }
    else{...}
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270