PHP strcmp не дает правильного вывода

Я сравниваю две строки по strcmp(1,2), и я получаю «-1» вместо 1, мой код ниже

  <?php
    echo strcmp(1,2);
   ?>

вывод: -1

введите описание изображения здесь

пожалуйста, дайте мне знать, почему я получаю -1 за ложь и как с этим справиться?


person NullPoiиteя    schedule 15.05.2012    source источник
comment
@ Джек, я знаю это, сэр, и поэтому я подумал, что вывод будет ложным 1, но его -1   -  person NullPoiиteя    schedule 15.05.2012
comment
Если первый аргумент меньше второго, он вернет отрицательное число.   -  person Ja͢ck    schedule 15.05.2012
comment
Почему вы используете функцию сравнения строк для сравнения чисел? Если вы хотите знать, если 22 меньше 9 - ›if (22 < 9) { ... }   -  person Ja͢ck    schedule 15.05.2012
comment
stackoverflow.com/questions/3333353/   -  person trante    schedule 16.01.2013
comment
@trante, спасибо .. эта ссылка действительно помогла ... еще раз спасибо   -  person NullPoiиteя    schedule 16.01.2013


Ответы (3)


1 меньше 2, strcmp определяется как возвращающий:

Возвращает ‹0, если str1 меньше str2; > 0, если str1 больше str2, и 0, если они равны.

Таким образом, поведение ожидается.


Обратите внимание на следующее предостережение:

Если вы полагаетесь на strcmp для безопасного сравнения строк, оба параметра должны быть строками, иначе результат будет крайне непредсказуемым. Например, вы можете получить неожиданный 0 или вернуть значения NULL, -2, 2, 3 и -3.

Из комментария на странице документации для strcmp.


PHP полон такого рода неожиданного поведения. В вашей ситуации я бы позаботился о том, чтобы оба аргумента были представлены как строки, чтобы избежать путаницы:

$first = 1;
$second = 2;
echo strcmp((string)$first, (string)$second);
person Michael Robinson    schedule 15.05.2012
comment
+1 Интересное поведение с -2 и -3. Удивительный :) - person Ja͢ck; 15.05.2012
comment
@Jack Я почти уверен, что это неявность приводит к строке. Что может случиться с некоторыми нечетными числовыми числами, так это то, что число слишком велико для представления, поэтому его нельзя правильно преобразовать в число (int / float) для последующего преобразования в строку. Изменить: на самом деле, посмотрев список поближе, это некоторые странные результаты. Неизвестно, как это реализовано ›.‹ - person Corbin; 15.05.2012
comment
@Corbin Я говорю об этом: strcmp(NULL, "foo") => -3 :) Большие числа легко объяснить, потому что они double сначала перед преобразованием в строку, теряя точность. - person Ja͢ck; 15.05.2012
comment
@Jack (строка) null ===; strcmp (, foo) === -3. Так что это никоим образом не шокирует, но я полагаю, что это действительно интересно (поскольку я не совсем уверен, откуда взялось 3 - основываясь на небольшом эксперименте, fooo возвращает -4, поэтому я думаю, что поведение может быть таким: вернуть strlen второй строки, если первая пуста). - person Corbin; 15.05.2012

Когда вы передаете int, он преобразуется в строку, о чем свидетельствует:

var_dump(strcmp('1', 2)); //-1

Причина -1 в том, что наиболее широко используемая реализация strcmp находит первый неравный символ и возвращает разницу.

Другими словами, это по существу «1» - «2», что составляет 49-50 (коды ASCII для «1» и «2»).

49-50 is -1.

Изменить: не совсем актуально, но из любопытства покопался. Это ни в коем случае не является гарантированным поведением в будущем, но начиная с PHP 5.4:

ZEND_FUNCTION(strcmp)
{
    char *s1, *s2;
    int s1_len, s2_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &s1, &s1_len, &s2, &s2_len) == FAILURE) {
        return;
    }

    RETURN_LONG(zend_binary_strcmp(s1, s1_len, s2, s2_len));
}


ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
{
    int retval;

    if (s1 == s2) {
        return 0;
    }
    retval = memcmp(s1, s2, MIN(len1, len2));
    if (!retval) {
        return (len1 - len2);
    } else {
        return retval;
    }
}

Он действительно преобразуется в строку.

person Corbin    schedule 15.05.2012

Вы не получите false.

Из руководства.

Возвращаемые значения

Возвращает ‹0, если str1 меньше str2; > 0, если str1 больше str2, и 0, если они равны.

person xdazz    schedule 15.05.2012