Why does this while loop repeat after the user has entered input that is too long?

Viewed 124
#include <stdio.h>
#include <ctype.h>

int stringLength (char *text)
{
  int count = 0;
  while (*text != '\0')
  {
    count++;
    text++;
  }
  return count;
}

int main()
{
  char str[25];
  int length;

  printf("Enter key: ");
  scanf("%[^\n]", str);

  length = stringLength(str);

  while (length > 24)
  {
    printf("Enter key: ");
    scanf("%[^\n]", str);
    length = stringLength(str);
  }
  printf("your string is: %s and its %d long", str, length);
  return 0;
}

Cant figure out why the while loop keeps repeating. The point of the code is to just calculate the length of a string (including spaces) and give out the result.

2 Answers

I assume you’re talking about this loop:

while (length > 24)
{
  printf("Enter key: ");
  scanf("%[^\n]", str);
  length = stringLength(str);
}

The conversion specifier %[^\n] reads characters up to, but not including, the next newline character, leaving that newline character in the input stream, which is what you want. The problem is that %[ doesn’t skip over leading whitespace, so on the next loop iteration it sees the \n from the previous input and immediately returns without reading anything and leaving str unchanged.

The quickest way to fix this is to put a leading blank in the format string - " %[^\n]". That will consume and discard the newline and any other leading whitespace left in the stream from the previous operation.

If’s also a good idea to put an explicit field width on the format so you don’t risk a buffer overflow - " %24[^\n]" (need to leave at least one space for the string terminator).

You should also check the return value of scanf, which is the number of successful conversions and assignments. In this case, it should be 1. If it’s 0 then you had a matching failure and str hasn’t been modified. If it’s EOF then you’ve either hit an end-of-file condition (possible if you’re redirecting standard input from a file or piping the result of another program) or there’s an error with the inpit stream itself.

Note that if length ever is greater than 24 then you’ve overrun your buffer and have entered the realm of undefined behavior.

The problem comes from scanf(), because it leaves enter on the end. The next function cycle takes the enter as the end of scanning, so it loads nothing. That's why your code keeps cycling at this point, when you pass input longer than 24 characters. You should use getchar() right after the scanf() input.

#include <stdio.h>

int stringLength (char *text)
{
  int count = 0;
  while (text[count] != '\0')
  {
    count++;
    // text++;
  }
  return count;
}

int main()
{
  char str[25];
  int length;
  do {
    printf("Enter key: ");
    scanf("%[^\n]", str);
    getchar();
    length = stringLength(str);
  }
  while (length > 24);

  printf("your string is: %s and its %d long", str, length);
  return 0;
}
Related