我们不能将字符串与回车 \r 进行比较吗?

1 c arrays string carriage-return string-comparison

我正在尝试使用strcmp()函数将字符串数组与单个字符串进行比较。当我使用没有\r回车的字符串时,它按预期工作正常,但是当我使用回车时,它不进行比较。为什么?

这是代码\r

#include <stdio.h>
#include <stdlib.h>         // For EXIT_SUCCESS & EXIT_FAILURE
#include <string.h>
int main()
{
    const char response[8][4]   =    {"DD1\r","DD2\r","DR1\r","DR2\r","SE1\r","SE2\r","SD1\r","SD2\r"};
    char *s                     =   "SD1\r";
    int i   =   0;
    int k   =   0;
    while(1)
    {
        k   =   strcmp(*(response+i),s);
        i++;
        if(k==0)
        {
            printf("Match Found\t%d\n",k);
            fflush(stdout);
            break;
        }
        if(i>12)
            break;
        printf("%d\t",i);
    }
}
 
Run Code Online (Sandbox Code Playgroud)

输出:

1   2   3   4   5   6   7   8   9   10  11  12
Run Code Online (Sandbox Code Playgroud)

这是没有\r.

#include <stdio.h>
#include <stdlib.h>         // For EXIT_SUCCESS & EXIT_FAILURE
#include <string.h>
int main()
{
    const char response[8][4]   =    {"DD1\r","DD2\r","DR1\r","DR2\r","SE1\r","SE2","SD1\r","SD2\r"};
    char *s                     =   "SE2";
    int i   =   0;
    int k   =   0;
    while(1)
    {
        k   =   strcmp(*(response+i),s);
        i++;
        if(k==0)
        {
            printf("Match Found\t%d\n",k);
            fflush(stdout);
            break;
        }
        if(i>12)
            break;
        printf("%d\t",i);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

1   2   3   4   5   Match Found 0
Run Code Online (Sandbox Code Playgroud)

我们不能将字符串与 \r 进行比较吗?

cal*_*hiz 6

是的,您确实可以与 进行比较\r,但真正的问题出在其他地方。

如果在这一行中将更改4为 a 5

前:

const char response[8][4] = {"DD1\r","DD2\r","DR1\r","DR2\r","SE1\r","SE2\r","SD1\r","SD2\r"};
Run Code Online (Sandbox Code Playgroud)

后:

const char response[8][5] = {"DD1\r","DD2\r","DR1\r","DR2\r","SE1\r","SE2\r","SD1\r","SD2\r"};
Run Code Online (Sandbox Code Playgroud)

strcmp 将按预期进行比较。

strcmp函数依赖于空字节来终止字符串。4 的问题在于字符串文字将在字节 4 ( \r)处被切掉。空字节无处可去,所以 to strcmpresponse看起来像"DD1\rDD2\rDR1\rDR2\rSE1\rSE2\rSD1\rSD2\r"加上后面的任何非空字节。因此,字符串文字总是比引号之间的长度多一个字节。因此,在您的情况下至少需要 5 个字节。

您的第二个代码“有效”的原因是因为 3 字节字符串没有被切掉,这意味着它正常进行比较。特别是,它将response两个单独的字符串视为:

  • "DD1\rDD2\rDR1\rDR2\rSE1\rSE2"
  • "SD1\rSD2\r" 加上尾随的非空字节。

附录:

如果大小不做必须是固定的,这样的效果要好得多:

const char* response[8] = {"DD1\r","DD2\r","DR1\r","DR2\r","SE1\r","SE2\r","SD1\r","SD2\r"};
Run Code Online (Sandbox Code Playgroud)

因为编译器会为您完成工作。

  • 好地方。一旦你传递了非 nul 终止的 `strcmp()` 东西,它就是 UB,所以在任何一种情况下,`char` 数组都需要是 5 个字节长。仅当比较的字符串缺少尾随“\r”时,它才会起作用,但它已经是 UB 了。 (2认同)