Usage of fgets function in C

泪湿孤枕 提交于 2019-11-29 11:28:51

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.

Reed Copsey

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

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)

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();

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.

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 ;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!