error: result of comparison against a string literal is unspecified for C

error: result of comparison against a string literal is unspecified for C

所以我想和 C 开个小玩笑,但我不知道我做错了什么。我看到错误“error: result of comparison against a string literal is unspecified”并且不知道如何解决它,有人可以帮忙吗。

#include<stdio.h>
#include<cs50.h>
int main(void){
    string a = get_string("ENTER YOUR NAME FOR READING\n");
    if (a == "david")
    ;
    {
        printf("...");
    }
}

您不能使用比较运算符比较 c 中的两个字符串。 尝试使用

strcmp(const char* one, const char* two)

也就是你的情况 使用

#include<stdio.h>
#include<cs50.h>
int main(void){
    char[] a = get_string("ENTER YOUR NAME FOR READING\n");
    char[] b = "david";
    if (!strcmp(a,"david"))
    {
        printf("...");
    }
}

此外,c 中的字符串未声明为字符串。它们被声明为 char 数组

编译器接受像这样比较两个字符指针 char *a, *b; a == b;,但是如果您使用这样的语法来比较字符串值,那么您可能得不到预期的结果。有时它可能计算为 true 或有时计算为 false。原因是,程序会检查 ab 是否指向相同的地址,而不是检查它们是否具有相同的字符串值。考虑下面的程序。

#include <stdio.h>
int main()
{
        char* a = "test";

        char* b;

        if ((b="test") == a)
                printf("Impossible\n");
        else
                printf("Thought so\n"); 

        printf("%p %p\n", a, b);

        return 0;
}

输出

Impossible
0x55b6bd52d004 0x55b6bd52d004

正如您从输出中看到的那样,if 块的计算结果为 true。原因也在输出中; ab 指向相似的地址。为什么?

It comes from the string-pooling, one of the compiler optimization. Even though a and b are initialized at different points in the program, as they are referring to the same string constant, the string constant is initialized only once by the compiler.

这是可执行文件的objdump

$ objdump -s -j .rodata 

a.out:     file format elf64-x86-64

Contents of section .rodata:
 2000 01000200 74657374 00496d70 6f737369  ....test.Impossi
 2010 626c6500 54686f75 67687420 736f0025  ble.Thought so.%
 2020 70202570 0a00                        p %p..          

test 只初始化一次。为了快速检查,请考虑该程序的输出及其 objdump .

#include <stdio.h>
int main()
{
        char* a = "test";

        char* b;

        if ((b="test1") == a)
                printf("Impossible\n");
        else
                printf("Thought so\n"); 

        printf("%p %p\n", a, b);

        return 0;
}

输出

Thought so
0x557a96aa9004 0x557a96aa9009

objdump

$ objdump  -s -j .rodata a.out  

a.out:     file format elf64-x86-64

Contents of section .rodata:
 2000 01000200 74657374 00746573 74310049  ....test.test1.I
 2010 6d706f73 7369626c 65005468 6f756768  mpossible.Though
 2020 7420736f 00257020 25700a00           t so.%p %p..

从输出中可以明显看出,ab 指向不同的位置,并且它们都具有不同的字符串值,这些值由编译器分别初始化。那么,如果 ab 具有相似的字符串值,那么 a==b 是否总是计算为真?考虑下面的程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 

int main()
{
        char* a = malloc(sizeof(char) * 5);
        strcpy(a, "test");

        char* b;

        if ((b="test") == a)
                printf("Impossible\n");
        else
                printf("Thought so\n"); 

        printf("%p %p\n", a, b);

        return 0;
}

输出

Thought so
0x5607d9938260 0x5607d91fb004

即使 ab 具有相同的字符串值,if 的计算结果为 false。为什么?地址a指向的是malloc()创建的属于可执行文件的堆段,而地址b指向的属于可执行文件的数据段,它们是确实不一样。

那么我们应该如何比较字符串值呢?

嗯,很简单,已经有库函数可以执行此任务。您可以将它们与 string.h 一起使用。考虑以下代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 

int main()
{
        char* a = malloc(sizeof(char) * 5);
        strcpy(a, "test");

        char* b = "test";

        char* c;

        if (strcmp((c="test"), a) == 0)
                printf("Impossible\n");
        else
                printf("Thought so\n"); 

        if (strcmp(b, a) == 0)
                printf("Impossible\n");
        else
                printf("Thought so\n"); 

        if (strcmp(b, c) == 0)
                printf("Impossible\n");
        else
                printf("Thought so\n"); 

        printf("%p %p %p\n", a, b, c);

        return 0;
}

输出

Impossible
Impossible
Impossible
0x556debf41260 0x556deac28004 0x556deac28004 

无论 abc 指向何处,如果它们都具有相同的字符串值,则 strcmp() returns 0

您的代码存在三个问题:

1.

if (a == "david")

a 衰减到指向数组 a.

第一个元素的指针

"david" 是字符串文字。

使用 if 语句,您尝试将数组 a 的地址与字符串文字 "david" 的地址进行比较。字符串比较在 C 中无法正常工作。

使用strcmp()-headerstring.h比较字符串。

strcmp() returns 如果字符串相等则为 0。要使 if 条件变为 true,您需要使用 ! 否定运算符。

2.

if 条件和 if body 之间错位了 ;。删除它。

3.

不推荐使用 cs50.h。如果您不需要明确使用它,请将您的手拿开。


#include <stdio.h>
#include <string.h>

int main (void) {
    char a[20];

    printf("ENTER YOUR NAME FOR READING:\n");

    if (!fgets(a, sizeof a, stdin))
    {
         fputs("Failure at input", stderr);
         // further Error routine.
    }

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

    if (!strcmp(a,"david"))
    {
        printf("...");
    }
}