2015-06-17 3 views
1

Я просто столкнулся с чрезвычайно странной проблемой. Функция у меня есть просто:C++ string.length() Странное поведение

int strStr(string haystack, string needle) { 

    for(int i=0; i<=(haystack.length()-needle.length()); i++){ 
     cout<<"i "<<i<<endl; 
    } 
    return 0; 
} 

Тогда, если я позвоню strStr("", "a"), хотя haystack.length()-needle.length()=-1, это не возвратит 0, вы можете попробовать это сами ...

+0

@aslg нет, вы можете попробовать размер() тоже такое же поведение. – Arch1tect

+0

@aslg Согласно [docs] (http://en.cppreference.com/w/cpp/string/basic_string/size), они не отличаются друг от друга. – Sinkingpoint

+0

Длина и размер такие же, насколько мне известно. 'I = 0; i <= -1; i ++ 'потребуется некоторое время, чтобы добраться до случая выхода. – user4581301

ответ

3

Это происходит потому, что .length().size()) вернуться size_t, который является неподписанным int. Вы думаете, что получаете отрицательное число, когда на самом деле оно возвращается к максимальному значению для size_t (На моей машине это 18446744073709551615). Это означает, что цикл for зациклится на всех возможных значениях size_t, а не просто выйдет немедленно, как вы ожидаете.

Чтобы получить результат, который вы хотите, вы можете явно преобразовать размеры в int с, а не unsigned int с (см aslgs ответа), хотя это может произойти сбой для строк с достаточной длиной (достаточно, чтобы над/под потоком стандартного int)

Edit: Два решения из приведенных ниже комментариев:

  1. (Nir Friedman) Вместо того, чтобы использовать int как в ответ aslg, в включают заголовок и используйте int64_t, что позволит избежать проблемы, упомянутой выше.

  2. (rici) Поверните свою петлю на for(int i = 0;needle.length() + i <= haystack.length();i ++){, чтобы избежать проблемы, переставив уравнение, чтобы избежать вычитания всех вместе.

+0

int не является такой хорошей рекомендацией по причинам, которые вы указали. На большинстве архитектур int составляет всего 32 бита. Вместо этого я бы рекомендовал #include и использовать int64_t или длинный длинный int (гарантированный минимум 64 бита). Это будет работать для всех строк, если ваш компьютер не имеет 2^63 байта ОЗУ. –

+0

Чтобы избежать проблемы, напишите условие: 'needle.length() + i <= haystack.length()' – rici

+0

@NirFriedman Я включил это предложение в свой ответ – Sinkingpoint

1
(haystack.length()-needle.length()) 

length возвращает size_t, другими словами без знака Int. Учитывая размер ваших строк, 0 и 1 соответственно, когда вы вычисляете разницу, она переполняется и становится максимально возможным значением для unsigned int. (Что составляет примерно 4,2 миллиардов для хранения 4 байта, но может быть другое значение)

i<=(haystack.length()-needle.length()) 

Индексатор i преобразуется компилятором в беззнаковое Int, чтобы соответствовать типу. Таким образом, вам придется подождать, пока i больше максимально возможного значения для unsigned int. Это не остановится.

Решение:

Вы должны преобразовать результат каждого метода в целое, как это так,

i <= ((int)haystack.length() - (int)needle.length()) 
+0

@Quirliom Исправлено. – aslg

Смежные вопросы