One of my assignments in to write my own UNIX Shell. To receive input from the user, I am using fgets to capture the input as a string but I\'m not really sure how it works.
Probably the easiest way to handle this is to switch to using scanf
to read the input:
char command[51];
scanf("%50[^\n]", command);
if (0 == strcmp(command, "exit"))
do_something();
As noted, fgets
(3) gives you the trailing '\n'. If you use gets
(3), you don't gets the trailing newline. Nothing like consistency, sez I.
Perl has a hand chomp() function that trims the trailing newline if its present — you could do worse than to roll your own:
#define NUL ((char)0)
void chomp( char *s )
{
if ( s != null )
{
int len = strlen(s) ;
if ( len >= 1 && s[len-1] == "\n" )
{
s[len-1] = NUL ;
}
}
return ;
}
fgets
considers the line terminator as a valid character. That's the extra character you are receiving.
Just do something like command[strlen(command) - 1] = '\0';
to remove the line terminator. Then you are free to do all your strcmp
's.
From the fgets manual page:
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.
Bottom-line: you have an extra newline at the end of your string when comparing.
fgets
is capturing the line break, too.
Note that you can overcome this in a few ways, one might be using strncmp
:
if((strncmp(command, "exit", 4)) == 0)
which checks if only the first 4 characters of command match (though this might not be the right option for you here).
Another tactic is to check with the line break in place:
if((strcmp(command, "exit\n")) == 0)
fgets
will always include the line termination character in the input string. You can remove any space, including the newline characters, from the end of your "command" by doing:
char command[50];
fgets(command, sizeof(command), stdin);
size_t length = strlen(command);
// Trim off trailing "spaces" including newline characters
while ((length > 0) && isspace(command[length-1]))
command[--length] = '\0';
printf("Your Command: %s\n", &command); // Include newline now...
// This is computed above...
// int length = strlen(command);
// Continue as before