Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Program won't terminate after compared to empty string

I am attempting to terminate my C program by checking for an empty string ("") but it seems not to work. I have tried to compare to "\0" as well but it was to no avail.

#include <stdio.h>
#include <string.h>

int main(void) {
    char nameInput[128];
    for(;;) {
        printf("Enter nation name: ");
        scanf("%s", nameInput);
        if(!strcmp(nameInput, "")){
            break;
        }
        printf("Got nation named \"%s\"\n", nameInput);
    }
    printf("All done getting nations!\n");
    return 0;
}
like image 960
Isaac Attuah Avatar asked Jan 23 '26 01:01

Isaac Attuah


2 Answers

The "%s" specifier in scanf("%s", nameInput); first consumes1 and discards leading white-space including all '\n' from the Enter before scanning and saving to nameInput.

That is why repeated entries of empty lines do not advance the scan. "%s" is waiting for some non-white-space input.


A better alternative to scanf() is to read all user input with fgets() and then parse the string.

fgets() reads a line and saves the result as a string - usually including the line's ending '\n'.

// scanf("%s", nameInput);
if (fgets(nameInput, sizeof nameInput, stdin)) {
  // Success at reading input.
  nameInput[strcspn(nameInput, "\n")] = '\0'; // lop off the potential trailing \n

  if(!strcmp(nameInput, "")){  // or simply `if(nameInput[0] == '\0')
    break;
  }
  ...

have tried to compare to "\0" as well but it was to no avail.

if(!strcmp(nameInput, "")) and if(!strcmp(nameInput, "\0")) do the same thing. strcmp() is comparing strings.

"" is a string literal of 1 char: the null character.
"\0" is a string literal of 2 char: two null characters.
The string compare stops at the first null character.


"%s" by itself also lacks a width limit. Code has no safe guard against input like "BlahBlah...(120_some_more)Blah" and can lead to undefined behavior due a buffer overrun of char nameInput[128];. Code could use "%127s" to prevent that, yet that only handles one of the short-comings of scanf().


1

Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier. C17dr § 7.21.6.2 8

like image 116
chux - Reinstate Monica Avatar answered Jan 25 '26 18:01

chux - Reinstate Monica


It's not that it won't terminate, it is awaiting the input that wasn't (yet) typed in.

scanf is not using the right pattern string to scan in anything (including nothing) before the carriage return. You'll need to look into scanf patterns, and alter your pattern from "%s" to something that scanf will accept as input.

If you test out your program, you will see that after pressing "enter" you can type in a word and press enter again, and since you now have a word in the input, the scanf picks it up (discarding the whitespace, as it should with "%s").

like image 36
Edwin Buck Avatar answered Jan 25 '26 17:01

Edwin Buck