Timothy Williams
Timothy Williams

Reputation: 217

While Loop isn't repeating?

This is a homework question. I am taking a C programming class. The requirement that I am working with now is

"If an empty message is entered, the user should be prompted to enter a non-empty message until they enter one which is at least 1 character long."

This is the code I have now:

int main(void)
{
char string[101];
int menu;

do
{
    printf("Enter a text message (maximum 100 characters long) : ");
    scanf(" %100[^\n]s", string);
}
while (string[0] == '\0');

If I take the space out in front of the % in the scanf line, and user just hits enter, the computer goes into an infinite loop and just prints gook to the screen. (The text on the screen is moving too fast for me to make sure, but I 'think' it is constantly printing the printf statement.)

With the space there, and the user just hits enter, it moves the cursor down to the next line until the user enters a valid string then moves on.

I want the question repeated every time the user just hits enter. I have tried empty for(;;), while and here you see the do-while variation.

Any comments welcome. Thanks.

Upvotes: 1

Views: 270

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126175

The basic problem without the space is that if the user just hits Enter, the scanf will fail (so nothing will be written to string), and NO INPUT WILL BE READ. So the newline will still be on the input, which means that when you loop, it will immediately fail again giving you an infinite loop.

With the space, the scanf call will read and ignore whitespace (including newlines) without returning, so when the user hits Enter it stay in the scanf.

The simplest solution is to just use fgets:

do {
    printf("Enter a text message (maximum 100 characters long) : ");
    if (!fgets(string, sizeof(string), stdin)) {
        /* error or eof */
        exit(1); }
} while (string[0] == '\n');

But this does not ignore leading whitespace on the line and will accept a line consisting only of spaces. If you want that, you'll need something like:

char *p;
do {
    printf("Enter a text message (maximum 100 characters long) : ");
    if (!fgets(string, sizeof(string), stdin)) {
        /* error or eof */
        exit(1); }
    p = string + strspn(string, " \t"); /* skip over leading spaces and tabs */
} while (p[0] == '\n' || p[0] == 0);

One of the major limitations of scanf is that its not good at distinguishing between spaces and newlines -- it treats both a whitespace.

Upvotes: 1

haccks
haccks

Reputation: 105992

Well, I would say better to use fgets:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char string[101];
    int menu;

    do
    {
        printf("Enter a text message (maximum 100 characters long) : ");
        fgets(string, 100, stdin);
    }while (string[0] == '\n');

}  

You should note that fgets do not discard \n character and reads it. When you will press Enter then \n will stored at string[0]. Therefore, you need to check string[0] == '\n'.

Upvotes: 1

Jim Lewis
Jim Lewis

Reputation: 45025

I would suggest using fgets rather than scanf, because for your purpose, you want to deal with a line at a time, and the input might contain embedded whitespace. You should check the user's input for trailing newlines and strip them (by replacing with '\0'). Then your while condition should work the way you want.

Upvotes: 3

Related Questions