C 警告:与字符串文字进行比较会导致未指定的行为

C 警告:与字符串文字进行比较会导致未指定的行为,c,C,我正在开始一个用C为linux编写简化shell的项目。我对C和linux都不精通,这正是我认为这是一个好主意的原因 从解析器开始,我已经遇到了一些问题 代码应该很简单,这就是为什么我没有包含任何注释 我在gcc中得到了一个警告:“与字符串文本进行比较会导致未指定的行为”,在“warning HERE”(请参阅下面的代码)注释行中 我不知道这为什么会导致警告,但真正的问题是,即使我在这里比较一个“)//警告 如果(args[i+1]!=NULL) cmd_info->outfile=args[i

我正在开始一个用C为linux编写简化shell的项目。我对C和linux都不精通,这正是我认为这是一个好主意的原因

从解析器开始,我已经遇到了一些问题

代码应该很简单,这就是为什么我没有包含任何注释

我在gcc中得到了一个警告:“与字符串文本进行比较会导致未指定的行为”,在“warning HERE”(请参阅下面的代码)注释行中

我不知道这为什么会导致警告,但真正的问题是,即使我在这里比较一个“)//警告 如果(args[i+1]!=NULL) cmd_info->outfile=args[i+1]; 其他的 返回-1; 其他的 cmd_info->arg[iarg++]=args[i]; } cmd_info->arg[iarg]=NULL; 返回0; } 无效打印命令(命令信息*命令信息) { int i; 对于(i=0;cmd_info->arg[i]!=NULL;i++) printf(“arg[%d]=\%s\“\n”,i,cmd\u info->arg[i]); printf(“arg[%d]=\%s\“\n”,i,cmd\u info->arg[i]); printf(“infle=\%s\”\n,cmd\u info->infle); printf(“outfile=\%s\”\n,cmd\u info->outfile); printf(“背景=\%d\”\n,cmd\u info->background); } int main(int argc,char*argv[]) { 字符命令行[100]; 命令信息命令信息; printf(“>>>”); fgets(cmd_线,100,标准尺寸); 解析命令(命令行和命令信息); 打印命令(&cmd\u信息); 返回0; }
'a'
'a'
之间有区别:

  • 'a'
    表示字符
    a
    的值
  • “a”
    表示存储字符串
    “a”
    的内存位置的地址(通常位于程序内存空间的数据部分)。在该内存位置,您将有两个字节——字符
    'a'
    和字符串的空终止符

    • 'a'
      'a'
      之间有区别:

      • 'a'
        表示字符
        a
        的值
      • “a”
        表示存储字符串
        “a”
        的内存位置的地址(通常位于程序内存空间的数据部分)。在该内存位置,您将有两个字节——字符
        'a'
        和字符串的空终止符

      在C中,无法将字符串与
      =
      进行比较。对于C,字符串只是(以零结尾的)数组,因此需要使用字符串函数来比较它们。请参阅手册页了解和


      如果要比较一个字符,需要比较的是字符,而不是字符串
      “a”
      是字符串
      a
      ,它占用两个字节(a
和终止的空字节),而字符
a
在C中由
'a'
表示。

在C中不能将字符串与
=
进行比较。对于C,字符串只是(以零结尾的)数组,因此,您需要使用字符串函数来比较它们。请参阅手册页了解和


如果要比较一个字符,需要比较的是字符,而不是字符串
“a”
是字符串
a
,它占用两个字节(a和终止的空字节),而字符
a
在C中由
'a'
表示。

您想使用
strcmp()==0
来比较字符串,而不是简单的
=
,如果指针是相同的(在本例中它们不会是相同的),则只会进行比较


args[i]
是一个指向字符串的指针(指向以null结尾的字符数组的指针),就像
“&”
“一样,您希望使用
strcmp()==0
来比较字符串,而不是简单的
=
,如果指针相同(在本例中它们不会相同),则只会进行比较

args[i]
是指向字符串的指针(指向以null结尾的字符数组的指针),正如
“&”
”
好吧,让我们看看这是怎么回事

args是指针数组。因此,这里您将比较
args[i]
(指针)与
“&”
(也是指针)。好的,唯一的方法是如果你在某处有
args[i]=“&”
,即使这样,
“&”
也不能保证在任何地方都指向同一个地方

我相信您实际上在寻找的是
strcmp
来比较整个字符串,或者您想做
if(*args[I]='&')
来比较
args[I]
字符串的第一个字符与
&
字符

好吧,让我们看看这是怎么回事

args是指针数组。因此,这里您将比较
args[i]
(指针)与
“&”
(也是指针)。好的,唯一的方法是如果你在某处有
args[i]=“&”
,即使这样,
“&”
也不能保证在任何地方都指向同一个地方

我相信您实际上在寻找的是
strcmp
来比较整个字符串,或者您想做
if(*args[I]='&')
来比较
args[I]
字符串的第一个字符与
&
字符

  • 在错误报告和恢复方面具有优势

    $ clang errors.c
    errors.c:36:21: warning: result of comparison against a string literal is unspecified (use strcmp instead)
            if (args[i] == "&") //WARNING HERE
                        ^~ ~~~
                strcmp( ,     ) == 0
    errors.c:38:26: warning: result of comparison against a string literal is unspecified (use strcmp instead)
            else if (args[i] == "<") //WARNING HERE
                             ^~ ~~~
                     strcmp( ,     ) == 0
    errors.c:44:26: warning: result of comparison against a string literal is unspecified (use strcmp instead)
            else if (args[i] == ">") //WARNING HERE
                             ^~ ~~~
                     strcmp( ,     ) == 0
    
    $clangerrors.c
    错误.c:36:21:警告:未指定与字符串文字进行比较的结果(请改用strcmp)
    如果(args[i]==“&”)//此处出现警告
    ^~ ~~~
    strcmp(,)==0
    错误.c:38:26:警告:未指定与字符串文字进行比较的结果(请改用strcmp)
    else if(args[i]==“”)//此处出现警告
    ^~ ~~~
    strcmp(,)==0
    
    它建议将
    x==y
    替换为
    strcmp(x,y)==0

  • 西铁
    if (args[i] == "&")
    
    $ clang errors.c
    errors.c:36:21: warning: result of comparison against a string literal is unspecified (use strcmp instead)
            if (args[i] == "&") //WARNING HERE
                        ^~ ~~~
                strcmp( ,     ) == 0
    errors.c:38:26: warning: result of comparison against a string literal is unspecified (use strcmp instead)
            else if (args[i] == "<") //WARNING HERE
                             ^~ ~~~
                     strcmp( ,     ) == 0
    errors.c:44:26: warning: result of comparison against a string literal is unspecified (use strcmp instead)
            else if (args[i] == ">") //WARNING HERE
                             ^~ ~~~
                     strcmp( ,     ) == 0
    
    "a"
    
    "This is a string"
    
    char *s1 = "This is a string";
    
    char *s2 = "This is a string";
    
    char *s3 = malloc( 17 );
    strcpy(s3, "This is a string");
    
    s1 == s2 // True: we are comparing two pointers that contain the same address
    
    s1 == s3 // False: Comparing two pointers that don't hold the same address.
    
    struct Vehicle{
        char *type;
        // other stuff
    }
    
    if( type == "Car" )
       //blah1
    else if( type == "Motorcycle )
       //blah2
    
    A.type = "Car";
    
    if( A.type == B.type )
    
    enum type {CAR = 0, MOTORCYCLE = 1}
    
    char *types[] = {"Car", "Motorcycle"};
    
    char *getTypeString(int type)
    {
        switch(type)
        case CAR: return "Car";
        case MOTORCYCLE: return "Motorcycle"
        default: return NULL;
    }
    
    //
    // This is the one include file that every user-written Nextest programs needs.
    // Patcom-generated files will also look for this file.
    //
    #include "stdio.h"
    #define IS_NONE( a_key )   ( ( a_key == "none" || a_key == "N/A" ) ? TRUE : FALSE )
    
    //
    // Note in my environment we have output() which is printf which adds /n at the end
    //
    main {
        char *psNameNone = "none";
        char *psNameNA   = "N/A";
        char *psNameCAT  = "CAT";
    
        if (IS_NONE(psNameNone) ) {
            output("psNameNone Matches NONE");
            output("%s psNameNoneAddr 0x%x  \"none\" addr 0x%X",
                psNameNone,psNameNone,
                "none");
        } else {
            output("psNameNone Does Not Match None");
            output("%s psNameNoneAddr 0x%x  \"none\" addr 0x%X",
                psNameNone,psNameNone,
                "none");
        }
    
        if (IS_NONE(psNameNA) ) {
            output("psNameNA Matches N/A");
            output("%s psNameNA 0x%x  \"N/A\" addr 0x%X",
            psNameNA,psNameNA,
            "N/A");
        } else {
            output("psNameNone Does Not Match N/A");
            output("%s psNameNA 0x%x  \"N/A\" addr 0x%X",
            psNameNA,psNameNA,
            "N/A");
        }
        if (IS_NONE(psNameCAT)) {
            output("psNameNA Matches CAT");
            output("%s psNameNA 0x%x  \"CAT\" addr 0x%X",
            psNameNone,psNameNone,
            "CAT");
        } else {
            output("psNameNA does not match CAT");
            output("%s psNameNA 0x%x  \"CAT\" addr 0x%X",
            psNameNone,psNameNone,
            "CAT");
        }
    }