0

I'm trying to get input from stdinusing fgets utilizing a character array with a size of 128 that is supposed to stop when it reads "exit" but it doesn't

char cmd[128];

if(fgets(cmd,128,stdin)=="exit"){
    //stuff
   }
Pyrromanis
  • 45
  • 10
  • tried using a printf("%s",cmd); using exit and it really prints exit without instead of terminating – Pyrromanis Oct 17 '16 at 19:22
  • 1
    Possible duplicate of [C String -- Using Equality Operator == for comparing two strings for equality](http://stackoverflow.com/questions/3933614/c-string-using-equality-operator-for-comparing-two-strings-for-equality) – n. m. could be an AI Oct 17 '16 at 19:36

1 Answers1

3

You can't compare strings with the == operator.

What you're actually doing here is comparing the function's return value (the address of cmd on success, NULL on failure) with the address of the string literal "exit". This will never be true.

You should check the return value for NULL, then use the strcmp function to compare cmd against "exit":

if ((fgets(cmd,128,stdin)) != NULL && 
    (strcmp(cmd,"exit\n") == 0 || strcmp(cmd,"exit\r\n") == 0) {
    ...

Note that the fgets function stores a newline in the buffer if one is read, so we need to add that to the string to check.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Will `strcmp` go belly up in the event of `fgets` returning null? – Ed Heal Oct 17 '16 at 19:24
  • 1
    Just to add to this, fgets will also read a newline into the buffer, so you need to use strncmp or add a newline to the string. – Jacob H Oct 17 '16 at 19:24
  • You'd need `strncmp` because the return from `fgets` would [probably] have a newline (i.e.) `exit\n` against `exit`, so it won't match as written – Craig Estey Oct 17 '16 at 19:24
  • 1
    [If `fgets()` hits `EOF` without reading any input or fails it returns `NULL`.](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html) `strcmp(fgets(cmd,128,stdin),"exit")` is asking for `SIGSEGV`. – Andrew Henle Oct 17 '16 at 19:25
  • Good catch @EdHeal and others. Edited. – dbush Oct 17 '16 at 19:31
  • @AndrewHenle i know i was just testing base case – Pyrromanis Oct 17 '16 at 19:32
  • 2
    `strncmp(cmd, "exit", 4)` will report a match on `"exitfoobar"` If you want to require the input to be exactly `"exit"`, then use `strcmp` to compare to `"exit\n"`. If you want to be more lax, you'll need to define exactly what qualifies as a match (`"Exit"`? `" exit "`?) and then write code to implement that. – Keith Thompson Oct 17 '16 at 19:34
  • How about the windows environment where `\n` will not suffice? – Ed Heal Oct 17 '16 at 19:37
  • 1
    This should be _two_ `if` statements: `if (fgets(...) == NULL) break;` to handle EOF (otherwise, the loop won't terminate). Then, a newline strip with `strlen` or `strchr`, and then `if (strcmp(...))` – Craig Estey Oct 17 '16 at 19:37
  • Edited to use `strcmp` instead of `strncmp`, and added checks for different newline styles. – dbush Oct 17 '16 at 19:39
  • @dbush - We got there eventually :-) – Ed Heal Oct 17 '16 at 19:41