Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用fgets读取线路上的strcmp_C_String_Input_Fgets_Strcmp - Fatal编程技术网

使用fgets读取线路上的strcmp

使用fgets读取线路上的strcmp,c,string,input,fgets,strcmp,C,String,Input,Fgets,Strcmp,我想比较两个字符串。一个存储在文件中,另一个从用户检索(stdin) 以下是一个示例程序: int main() { char targetName[50]; fgets(targetName,50,stdin); char aName[] = "bob"; printf("%d",strcmp(aName,targetName)); return 0; } 在该程序中,strcmp在输入为“bob”时返回-1的值。 为什么会这样?我认为他们应该平等

我想比较两个字符串。一个存储在文件中,另一个从用户检索(stdin)

以下是一个示例程序:

int main()
{
    char targetName[50];
    fgets(targetName,50,stdin);

    char aName[] = "bob";
    printf("%d",strcmp(aName,targetName));

    return 0;
}
在该程序中,
strcmp
在输入为
“bob”
时返回-1的值。
为什么会这样?我认为他们应该平等。我怎样才能得到它呢

因为fgets正在将换行符嵌入变量
targetName
。这就放弃了比较。

fgets
将换行符附加到字符串中,因此您将以
bob\n\0
结束,这与
bob\0
不同,这主要是因为在类unix系统下,输入“\n”中的行尾字符。

fgets
读取直到看到换行符后返回,因此,在控制台中键入bob时,
targetName
包含与“bob”不匹配的“bob\n”。 来自fgets文档:(加粗)

从流中读取字符并将其作为C字符串存储到str中,直到读取(num-1)个字符或到达换行符或文件末尾,以先到者为准。 换行符使FGET停止读取,但它被视为有效字符,因此它包含在复制到str的字符串中。 在读取字符后,空字符会自动追加到str中,以表示C字符串的结束

在比较之前,需要删除targetName末尾的换行符

int cch = strlen(targetName);
if (cch > 1 && targetName[cch-1] == '\n')
   targetName[cch-1] = '\0';
或者将换行符添加到测试字符串中

char targetName[50];
fgets(targetName,50,stdin);

char aName[] = "bob\n";
printf("%d",strcmp(aName,targetName));

strcmp
是少数几个结果相反的函数之一…如果字符串相等,则结果为0,而不是您认为的1

if (strcmp(a, b)) {
    /* Do something here as the strings are not equal */
} else {
    /* Strings are equal */
}
说到
fgets
,很可能字符串的末尾附加了一个换行符…您需要去掉它

+-+-+-+--+--+
|b|o|b|\n|\0|
+-+-+-+--+--+
为了摆脱新行,请这样做。 注意事项:不要使用“strlen(aName)-1”,因为fgets返回的行可能以NUL字符开头-因此缓冲区中的索引变为-1:

aName[strcspn(aName, "\n")] = '\0';

+-+-+-+--+
|b|o|b|\0|
+-+-+-+--+

现在,
strcmp
应该返回0…

fgets正在向用户输入的字符串追加一个
\n
。您可以通过使用
strcspn
或仅在要比较的字符串末尾添加
\n
来解决此问题

printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: \n");
fgets(temp, 8, stdin);
temp[strcspn(temp, "\n")] = '\0';
if(strcmp(temp, "ls") == 0 || strcmp(temp, "exit") == 0)
这只是将
\n
替换为
\0
,但是如果你想变得懒惰,你可以这样做:

printf("Please enter put FILE_NAME (foo1, 2, or 3), ls, or exit: \n");
fgets(temp, 8, stdin);
if(strcmp(temp, "ls\n") == 0 || strcmp(temp, "exit\n") == 0)

但是它没有那么优雅。

我建议使用
sizeof(targetName)
,不要在
fgets()中硬编码它。
。谢谢,其他答案很好,但您的答案中包含了一个解决方案(我认为问题可能是\n,但也可能是其他问题),因为您包含了一个解决方案(和一个漂亮的数组图片lol),我把你的评为最好的。是的,现在strcmp起作用了。strcmp不会逆转真与假的结果。strcmp不会返回布尔值,它会根据两个字符串之间的关系返回一个整数值。“if(strcmp(a,b))”有效,但掩盖了这一事实,因为在处理整数值时,“if”语句将其视为“if(n!=0)”。一种更清晰的书写方式是“if(strcmp(A,b)!=0)”,它明确地说明了正在测试的内容。@Torlack:或者if(!strcmp(A,b))……不管你说什么,任何非零的都是真的,零是假的,因此我强调它……是的,如果匹配,strcmp实际上返回0,否则,如果一个比另一个小,它将是一个负数;如果一个比另一个大,它将是一个正数(它做了一些奇怪的数学运算,哈哈),但它在某种程度上是颠倒的,0表示“真”,1或任何其他数字=假。如果你只是把返回值看作“差异的数量”,那就更有意义了。但是你的说法仍然是错误的,因为它是相反的。如果你所说的是真的,那么“如果(STRCMP(a,b)!= true)”也是正确的,但它不是(假设我们在用C或C++的版本来实现,而布尔的正确实现只能是真和假的状态)。您应该避免使用strcmp。请改用
strncmp
,尤其是在与固定宽度的字符串进行比较时。使用
strncmp(aName,targetName,strlen(aName))
应该适合您。bta的注释是错误的——如果您想检查前缀,而不是整个字符串,请使用strncmp,例如“bobcat”也将匹配。我说这是因为strcmp将继续比较,直到到达空终止符或字符串不同。如果您不能确定字符串总是正确地以NULL结尾,
strcmp
会导致缓冲区溢出和内存访问冲突
strncmp
不仅仅用于读取前缀;将最后一个参数设置为固定长度缓冲区的大小,以确保不会溢出数组边界。bta-您的原始注释要求使用
strlen
计算
strncmp
的size参数。这样做不会增加
strcmp
尚未提供的额外保护。当应使用
strncmp
时,使用固定的大小值(如第二条注释所示的缓冲区大小)。