4

我的一项任务是编写自己的 UNIX Shell。为了接收用户的输入,我使用 fgets 将输入捕获为字符串,但我不确定它是如何工作的。当我运行时:

char command[50];
fgets(command, sizeof(command), stdin);

printf("Your Command: %s", &command);
int length = strlen(command);
printf("Length of String: %d\n", length);

可以说我的输入是“退出”。strlen 表示字符串长度为 5 个字符,而不是 4 个。我想做这个:

if( (strcmp(command, "exit")) == 0 ){
    doSomething();
}

但是命令永远不会等于我想要的字符串;它就像它有一个我不确定的未知字符。它是最后的空字符吗?如何更改 if 语句以检查 fgets 捕获的用户输入是否等于“exit”?谢谢!

4

7 回答 7

7

fgets将行终止符视为有效字符。那是您收到的额外字符。

只需执行类似command[strlen(command) - 1] = '\0';删除行终止符的操作。然后你就可以自由地做你所有的事情了strcmp

于 2011-02-04T01:06:50.560 回答
4

fgets手册页:

fgets() 从流中最多读入一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止读取。 如果读取了换行符,则将其存储到缓冲区中。 '\0' 存储在缓冲区中的最后一个字符之后。

底线:比较时,您的字符串末尾有一个额外的换行符。

于 2011-02-04T01:08:23.530 回答
3

fgets将始终在输入字符串中包含行终止字符。您可以通过执行以下操作从“命令”末尾删除任何空格,包括换行符:

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
于 2011-02-04T01:13:08.060 回答
2

fgets也在捕获换行符。

请注意,您可以通过几种方式克服这一点,其中一种可能是使用strncmp

if((strncmp(command, "exit", 4)) == 0)

它检查是否只有命令的前 4 个字符匹配(尽管这可能不是您的正确选择)。

另一种策略是检查换行符是否到位:

if((strcmp(command, "exit\n")) == 0)
于 2011-02-04T01:07:32.667 回答
2

处理这个问题的最简单方法可能是切换到使用scanf来读取输入:

char command[51];

scanf("%50[^\n]", command);

if (0 == strcmp(command, "exit"))
    do_something();
于 2011-02-04T01:38:08.677 回答
1

您的字符串末尾仍有换行符。您可以比较"exit\n"或使用类似strncmp(command, "exit", 4). 请注意,这将接受以“exit”开头的任何内容并忽略其余内容。

于 2011-02-04T01:08:15.857 回答
0

如前所述,fgets(3) 为您提供了尾随的 '\n'。如果使用gets(3),则不会得到尾随换行符。没有什么比一致性更好的了,sez I。

Perl 有一个手动 chomp() 函数,如果它存在,它会修剪尾随的换行符——你可以做的比自己滚动更糟糕:

#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 ;
}
于 2011-02-04T01:21:43.913 回答