Верно и неверно в C в операторе if с помощью getopt () - PullRequest
0 голосов
/ 19 ноября 2018

Мне трудно понять, как работает true и false с оператором if, когда я использую argv & getopt.

Это простой код:

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

int main(int argc, char *argv[]) {
        int opt;

while ((opt = getopt (argc, argv, "i:l:")) != -1)
        switch (opt) {
        case 'i':
                printf("This is option i");           
                break;
        case 'l':
                printf("This is option l");
                break;
        default:
                fprintf(stderr,"Usage: %s here goes usage\n",argv[0]); 
    }

if (argc == 1) {
    printf("Without options");
}

if ((argc == 2) && (argv[1] != "-l") || (argv[1] != "-i")) {
    printf("Without option -l or -i but with other argument \n");
    printf("argv[1] is %s\n", argv[1]); 
}

Использование:

./a.out foo

Выход:

Without option -l or -i but with other argument 
argv[1] is foo

Пока все хорошо. Теперь позвольте мне проверить, работает ли он, когда argv [1] равен "-l":

Использование:

./a.out -l

Выход:

./a.out: option requires an argument -- 'l'
Usage: ./a.out here goes usage
Without option -l or -i but with other argument 
argv[1] is -l

Getopt работает нормально, но вторая информация появляется, даже если argv [1] равен -l, и я установил в операторе if это (argv [1]! = "-L"). Почему это так работает? Понятия не имею.

Спасибо за любой ответ. B.

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

Вы сравниваете два char * с использованием !=, это сравнивает адреса.

(argv[1] != "-l")

Для сравнения строк используется strcmp. Имейте в виду, что функция strcmp имеет значение «trinary» и возвращает либо отрицательное, либо положительное значение, если строки различаются (для обеспечения порядка), или 0, если оно равно.

(strcmp(argv[1], "-l") == 0)

0 голосов
/ 19 ноября 2018

AND (&&) имеет приоритет над OR (||), поэтому я думаю, что ваш код внутри оператора if интерпретируется следующим образом:
if (((argc == 2) && (argv[1] != "-l")) || (argv[1] != "-i"))
Так что логика внутри неговсегда верно, потому что даже если ваш вариант IS -l и он один-единственный (число вариантов! = 2), также верно, что введенный вами вариант НЕ -i.

0 голосов
/ 19 ноября 2018

Do not use:

argv[1] != "-l"

для сравнения строк в C (a) , это сравнивает адреса двух массивовchar (b) , а не содержимое этих двух строк.Instaed, вы должны использовать:

strcmp(argv[1], "-l") == 0

(a) Это одна из вещей, исправленных в строках C ++, там операторы равенства сравнивают содержимое строк.

(b) Это может иногда работать с чем-то вроде "xyzzy" == "xyzzy", но это только потому, что компилятору разрешено (но не обязательно) складывать одинаковую строкуконстанты вместе (поэтому они занимают меньше места).Обычно это невозможно, когда одна из строк не является константой (например, когда она передается в командной строке).

...