strcmp не может правильно сравнить строки

У меня проблемы с использованием strcmp в C.

Я пытаюсь сравнить аргументы программы, используя strcmp, но даже если строки одинаковы, это не работает. Вот часть кода.

while(strcmp(argv[i], "-e") != 0)

Итак, для i = 11, если я напечатаю значение argv[i], я получу

printf("String %s i %d", argv[i],i);

>> String -e i 11

Но время продолжается. Есть идеи, почему это происходит?

Код:

while(strcmp(argv[i], "-e") != 0 || i != argc)
{
    printf("String %s i %d", argv[i],i);
    if(!isdigit((unsigned char)*argv[i]) && strcmp(argv[i], "-t") != 0)
    {
        archivo = fopen(argv[i] , "r");
        TOT_IMG = TOT_IMG + 1;
        for(t=0;t<NUM_FUNC_TRAZO;t++)
        {
            for(d=0;d<NUM_FUNC_DIAMETRICA;d++)
            {
                for(c=0;c<NUM_FUNC_CIRCO;c++)
                {
                    if (fscanf(archivo, "%s",el) != EOF)
                    {
                        par->vector_circo[t][d][c] = strtod(el,NULL);
                        par->clase = clase;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        par_temp = par;
        par->siguiente = (parametros_lista) malloc(sizeof(parametros_elem));
        par = par->siguiente;
        par->anterior = par_temp;
    }
    else
    {
        if(strcmp(argv[i], "-t") != 0)
        {
            clase = atoi(argv[i]);
            CLASES = CLASES + 1;
        }
    }
    i = i + 1;
}

person Atirag    schedule 22.03.2013    source источник
comment
Вы точно не забыли i++;?   -  person    schedule 23.03.2013
comment
Вставьте полный код, а не два отрывка без пояснений, как они связаны.   -  person David Schwartz    schedule 23.03.2013
comment
Нет, я слежу за значением i с помощью отладчика, и все в порядке. Выложу остальную часть кода.   -  person Atirag    schedule 23.03.2013


Ответы (2)


Давайте посмотрим на это:

while(strcmp(argv[i], "-e") != 0 || i != argc)

Итак, давайте предположим, что strcmp правильно возвращает 0, когда argv[i] равно "e". Мы предполагаем это, потому что крайне маловероятно, что в вашей библиотечной реализации strcmp есть ошибка.

Что произойдет, если strcmp вернет 0? Что ж, вещи не просто останавливаются, ваш код проверяет, верно ли i != argc. Это? Мои навыки психической отладки говорят мне, что вам следует изучить вторую часть while.

Вы также можете отметить, что ваш код потенциально может получить доступ к argv[argc], что равно NULL. Вам может повезти, если strcmp снисходителен, когда ввод NULL, но это ошибка, которую вы должны исправить.

person Nik Bougalis    schedule 22.03.2013
comment
Я бы добавил, что while(i < argc && strcmp(argv[i], "-e") != 0) здесь, вероятно, лучший выбор. - person D.Shawley; 23.03.2013
comment
хм, хорошо, но я использую || в инструкции while, поэтому первая часть while должна действовать независимо от второй части, не так ли? Я собираюсь удалить вторую часть, чтобы проверить это - person Atirag; 23.03.2013
comment
@Omri: Круто, каждый день узнаешь что-то новое. Спасибо, я отредактирую соответственно. - person Nik Bougalis; 23.03.2013
comment
@Atirag подумайте о том, как работает || - если левая часть ложна, она проверяет правую, если левая часть верна, она не проверяет правую сторону. - person Nik Bougalis; 23.03.2013

Я бы рекомендовал вам использовать getopt (3). Это широко используемый подход к разбору параметров в соответствии с POSIX.

Также был еще один вопрос, связанный с достижением интерфейса getopt.h в Windows: getopt.h : компиляция C-кода UNIX в Windows. Что важно, на него ответили (Xgetopt), так что о переносимости не должно быть и речи.

person Roman Nikitchenko    schedule 22.03.2013
comment
getopt НЕ является частью стандарта C. Это POSIX. - person cli_hlt; 23.03.2013
comment
@cli_hlt POSIX определяет стандартную библиотеку POSIX C. - person ; 23.03.2013
comment
IEEE POSIX не имеет ничего общего со стандартом ANSI C. Гугл вам объяснит. @ Роман, ты должен уточнить свой ответ там. - person cli_hlt; 23.03.2013
comment
@cli_hit где ты нашел слово "ANSI" даже в исходном посте (хорошо, теперь я вообще удалил слово "стандарт", чтобы не кормить троллей)? Да, это POSIX, разве это не стандарт? Специально для вас: en.wikipedia.org/wiki/C_POSIX_library - person Roman Nikitchenko; 23.03.2013
comment
@RomanNikitchenko POSIX — это стандарт, он определяет операционные системы, совместимые с POSIX. Для операционных систем, совместимых с POSIX(!) требуется библиотека POSIX C. Например, *nix — это такая ОС. ОТО, винды нет. ANSI C — это стандарт языка программирования C. Программы, совместимые с ANSI C, работают на любой системе, в которой есть компилятор, совместимый с ANSI C. ANSI C также имеет стандартную библиотеку, которая вместе с описанием языка определяет язык программирования C. Очень важно не перепутать эти вещи. - person cli_hlt; 23.03.2013