可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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. When I run:
char command[50];
fgets(command, sizeof(command), stdin);
printf("Your Command: %s", &command);
int length = strlen(command);
printf("Length of String: %d\n", length);
Lets say my the input was "exit". strlen says that the string is 5 characters long, instead of four. I want to do this:
if( (strcmp(command, "exit")) == 0 ){
doSomething();
}
but command is never equaling the string that I want it to; its like it has an unknown character that Im not sure of. Is it the null character at the end? How do I change the if statement to check that the user input caught with fgets equals "exit"? Thanks!
回答1:
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.
回答2:
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.
回答3:
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
回答4:
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)
回答5:
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();
回答6:
Your string still has the newline at the end. You could compare with "exit\n"
or use something like strncmp(command, "exit", 4)
. Note that that would accept anything that started with "exit" and ignore the rest.
回答7:
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 ;
}