2015-03-14 2 views
-4

Я видел, что часть моего кода не работает должным образом. Он не входит в инструкцию if и дает ошибку, пока это необходимо. Я попытался изучить код и нашел что-то очень странное. Когда я добавляю cout << i в цикле for, чтобы проверить, он начинает работать хорошо. Может ли кто-нибудь объяснить, в чем проблема? Примечание. airports - это vector объектов Аэропорта. Airport::getName() возвращает свое имя string.Странное поведение кода

string name = "smth"; 
//this is the loop with unexpected behaviour 
for (int i = 0; i < airports.size(); i++) 
{ 
    //when the following line is taken outside the comment, it works well: 
    //cout << i; 
    if (isEqualNoCaseSense(name, airports[i].getName())) 
    { 
     cout << "Could not create airport " << name << ". It already exists." << endl; 
     return; 
    } 
} 

Функция I используется для сравнения строк без учета регистра:

bool isEqualNoCaseSense(string str1, string str2) 
{ 
if (str1.size() != str2.size()) 
    return false; 
char *lowerStr1 = new char[str1.size()]; 
char *lowerStr2 = new char[str2.size()]; 
for (int i = 0; i < str1.size(); i++) 
{ 
    lowerStr1[i] = tolower(str1[i]); 
    lowerStr2[i] = tolower(str2[i]); 
} 
if (strcmp(lowerStr1, lowerStr2) == 0) 
{ 
    delete[] lowerStr1; 
    delete[] lowerStr2; 
    return true; 
} 
else 
{ 
    delete[] lowerStr1; 
    delete[] lowerStr2; 
    return false; 
} 
} 

EDIT: Коррекция функции сравнения фиксирует ее, но я до сих пор удивляюсь, почему cout << i установил ее

+1

Ваши массивы 'char' не имеют нулевого конца (необходимо для' strcmp'). Но в действительности ты им не нужен. Просто найдите stackoverflow для сравнения строк без учета регистра. – juanchopanza

+1

Oh-em-gee. Эта чудовищная функция сравнения! просто не надо. –

+0

@ TheParamagneticCroissant вы можете сосредоточиться на вопросе :)) – farukdgn

ответ

3

Проблема заключается в том, что вы не имеете прекращено ваши строки, но если вы просто написать функцию толковой не будет работать правильно:

bool isEqualNoCaseSense(const string& str1, const string& str2) 
{  
    if (str1.size() != str2.size()) 
     return false; 
    for (int i = 0; i < str1.size(); ++i) 
     if (tolower((unsigned char)str1[i]) != tolower((unsigned char)str2[i])) 
      return false; 
    return true; 
} 

нет ненужное выделение, и петля только через строку до первого несовпадения.

EDIT: исправляющие функцию сравнения фиксирует ее, но я до сих пор удивляюсь, почему cout << i установил ее

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

+1

Нет ли предупреждения о том, как использовать 'tolower' с' char'? Я помню, что мне приходилось иметь дело с тем, что в последний раз, когда я отвечал на этот вопрос ... – juanchopanza

+0

@juanchopanza, да, его действительно нужно отличить от 'unsigned char', но для известного входа ASCII значения не будут отрицательными, даже если ваш' char' подписан. Если в входных строках могут быть символы> 127, то необходим бросок. –

+0

Говоря о предупреждениях, вы должны объявить 'i' либо как' size_t', либо 'std :: string :: size_type' из-за несоответствия подписанного/неподписанного или возможной потери данных на 64 бит. – Axalo

1

strcmp ОЖИДАЕТ Строки с нулевым завершением. Поэтому вам нужно зарезервировать еще один символ для массивов lowerStr1, lowerStr2 и установить последний символ каждого массива в NULL. В противном случае создайте неопределенный бахавир для своей программы.

Но вы могли бы обойти все эти вопросы, если вы используете функцию strncmp проходящее str1.size() в качестве третьего аргумента, так как вы уже проверить, если две строки имеют одинаковый размер:

if (strncmp(lowerStr1, lowerStr2, str1.size()) == 0) 
+2

Это просто делает ужасное и неэффективное решение. Но фиксированный код все еще ужасен и неэффективен. – juanchopanza

+0

Хорошо, но почему это работает, когда я добавляю 'cout << i;'? – farukdgn

+2

Поскольку программа имеет неопределенное поведение, все может случиться. –

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