0

I have the following code in C:

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

int main(int argc, char *argv[])
{

    char *buf;

    buf = malloc(sizeof(char) * 512);


    while(strcmp(buf, "Exit!") != 0 )
    {
        printf("Enter something:");
        fgets(buf, sizeof(char) * 512, stdin);
        printf("You entered %s\n", buf);

        printf("%d\n", strcmp(buf, "Exit!"));

    }

}

The behavior I want is for the while loop to terminate when the user enters the specified string. From what I understand, I am able to use a char pointer to represent a string in C. I am storing the user input using fgets() and comparing using the strcmp() function. I added a debug statement that prints out the result of this comparison and it returns a positive integer when I enter "Exit!" which should terminate the while loop.

Could someone explain what I am missing? I believe it has something to do with a new line character or the C-String terminator \0. How do I get the while loop to terminate when the user enters "Exit"?

Ferrazeth
  • 33
  • 4
  • `fgets` read *and includes* the trailing `'\n'` with each line it reads. – David C. Rankin Oct 20 '16 at 06:59
  • You should also `break` the loop if `fgets` returns `NULL`. Without that check, the code will go into an infinite loop if the user presses the key combination that generates `EOF`. That key combination is control-D on unix systems, and control-Z on windows. – user3386109 Oct 20 '16 at 07:03
  • Also, after the `malloc`, you should have the line `buf[0] = '\0';` That avoids the (extremely unlikely) chance that the buffer returned by `malloc` contains the string `"Exit!"` – user3386109 Oct 20 '16 at 07:07

1 Answers1

1

It is because fgets retains the newline that was entered from the keyboard, or marked the end of the line in the text file.

One simple way to remove it is like this:

#include <string.h>

//...

buf [ strcspn(buf, "\r\n") ] = 0;   // remove trailing newline etc
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • Surely that is a bad idea, because if the pattern isn't in the string, you could overflow buf by one byte? – Secto Kia Oct 20 '16 at 10:30
  • 1
    @SectoKia it is completely safe. If neither `\n` or `\r` are present, it overwrites the exisiting `'\0'` terminator, otherwise it overwrites the first match. – Weather Vane Oct 20 '16 at 16:09