1. ホーム
  2. c

[解決済み] 警告: 文字列リテラルとの比較は特定されない動作になる

2022-02-01 15:30:08

質問

私はC言語とLinuxに全く精通していないのですが、それがまさに良いアイデアだと思った理由です。

パーサーから始めて、すでにいくつかの問題に遭遇しています。

コードは簡単なはずなので、コメントを入れなかったのはそのためです。

gccで警告が表示されます: "WARNING HERE"でコメントされた行で、 "string literals results in unspecified behaviour" (以下のコードを参照してください).

なぜこれが警告を引き起こすのか見当もつきませんが、本当の問題は "<" と "<" を比較しているにもかかわらず、if の中に入ってこないということです...。

私は説明された問題に対する答えを探していますが、もしコードに何か改善すべき点があれば言ってください。ただ、私はそれほど熟練しておらず、これはまだ進行中の作業であることを心に留めておいてください。

よろしくお願いします。

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

typedef enum {false, true} bool;

typedef struct {
    char **arg;
    char *infile;
    char *outfile;
    int background;
} Command_Info;

int parse_cmd(char *cmd_line, Command_Info *cmd_info)
{
    char *arg;
    char *args[100];    

    int i = 0;
    arg = strtok(cmd_line, " \n");
    while (arg != NULL) {
        args[i] = arg;
        arg = strtok(NULL, " \n");
        i++;
    }

    int num_elems = i;

    cmd_info->infile = NULL;
    cmd_info->outfile = NULL;
    cmd_info->background = 0;

    int iarg = 0;
    for (i = 0; i < num_elems; i++)
    {
        if (args[i] == "&") //WARNING HERE
            return -1;      
        else if (args[i] == "<") //WARNING HERE
            if (args[i+1] != NULL)
                cmd_info->infile = args[i+1];
            else
                return -1;

        else if (args[i] == ">") //WARNING HERE
            if (args[i+1] != NULL)
                cmd_info->outfile = args[i+1];
            else
                return -1;          

        else 
            cmd_info->arg[iarg++] = args[i];
    }

    cmd_info->arg[iarg] = NULL;

    return 0;   
}

void print_cmd(Command_Info *cmd_info)
{
    int i;  
    for (i = 0; cmd_info->arg[i] != NULL; i++)
        printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);
    printf("arg[%d]=\"%s\"\n", i, cmd_info->arg[i]);    
    printf("infile=\"%s\"\n", cmd_info->infile);
    printf("outfile=\"%s\"\n", cmd_info->outfile);
    printf("background=\"%d\"\n", cmd_info->background);
}

int main(int argc, char* argv[])
{
    char cmd_line[100];
    Command_Info cmd_info;

    printf(">>> ");

    fgets(cmd_line, 100, stdin);

    parse_cmd(cmd_line, &cmd_info);

    print_cmd(&cmd_info);

    return 0;
}

解決方法は?

を使用したい。 strcmp() == 0 の代わりに文字列を比較するために、単純な == この場合、ポインタが同じかどうかを比較するだけです(この場合、同じにはなりませんが)。

args[i] は文字列へのポインタ(ヌル文字で終端する配列へのポインタ)であり、同様に "&" または "<" .

式は argc[i] == "&" は、2 つのポインタが同じかどうか (同じメモリ位置を指しているかどうか) をチェックします。

式は strcmp( argc[i], "&") == 0 は、2つの文字列の内容が同じかどうかをチェックします。