我编写自己的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捕获的用户输入是否等于“退出”?谢谢!
答案 0 :(得分:7)
fgets
将行终止符视为有效字符。这是你收到的额外角色。
只需执行command[strlen(command) - 1] = '\0';
之类的操作即可删除行终止符。然后你可以自由地完成所有strcmp
。
答案 1 :(得分:4)
从fgets
手册页:
fgets()从流和存储中读取最多一个小于大小的字符 它们进入s指向的缓冲区。读数在EOF或换行符后停止。 如果读取换行符,则将其存储到缓冲区中。之后存储“\ 0” 缓冲区中的最后一个字符。
底线:比较时,字符串末尾有一个额外的换行符。
答案 2 :(得分: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
答案 3 :(得分:2)
fgets
也正在捕捉换行符。
请注意,您可以通过几种方式克服此问题,可能正在使用strncmp
:
if((strncmp(command, "exit", 4)) == 0)
检查命令的前4个字符是否匹配(虽然这可能不适合你)。
另一种策略是检查换行符:
if((strcmp(command, "exit\n")) == 0)
答案 4 :(得分:2)
处理此问题的最简单方法可能是切换到使用scanf
来读取输入:
char command[51];
scanf("%50[^\n]", command);
if (0 == strcmp(command, "exit"))
do_something();
答案 5 :(得分:1)
你的字符串最后仍然有换行符。您可以与"exit\n"
进行比较,或使用strncmp(command, "exit", 4)
之类的内容。请注意,这将接受任何以“exit”开头的内容并忽略其余内容。
答案 6 :(得分: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 ;
}