Usage of fgets function in C

2019-01-26 15:45发布

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!

7条回答
淡お忘
2楼-- · 2019-01-26 16:12

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 ;
}
查看更多
对你真心纯属浪费
3楼-- · 2019-01-26 16:14

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();
查看更多
你好瞎i
4楼-- · 2019-01-26 16:19

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
查看更多
冷血范
5楼-- · 2019-01-26 16:25

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.

查看更多
走好不送
6楼-- · 2019-01-26 16:25

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楼-- · 2019-01-26 16:28

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.

查看更多
登录 后发表回答