Не соответствует оператору == в функции

Я работаю над проектом расшифровки Цезаря, и в функции CaesarDecipher я продолжаю получать эту ошибку при компиляции:

ошибка: нет совпадения для 'operator==' в 'textInit.std::basic_string‹_CharT, _Traits, >_Alloc>::operator[] [с _CharT = char, _Traits = std::char_traits, _Alloc >= std:: распределитель](((длинное целое число без знака)i)) == алфавит[j]'

Вот код этой функции:

string CipherMessage::CaesarDecipher(string key)
{
  int keyValue;
  int charValue;
  string textInit = m_text;
  string textFinal;
  // Initializes an array containing the alphabet. A=index 0, B=index 1, etc
  string alphabet[26] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","\
O","P","Q","R","S","T","U","V","W","X","Y","Z"};

  for (int i=0; i<=25; i++){
    if (alphabet[i] == key)
      keyValue = i;
  }
for (int i=0; i<=textInit.length(); i++){
    for (int j=0; j<=25; j++){
      if (textInit[i] == alphabet[j])   // Error occurs here
        charValue = j;
    }
    charValue = (charValue+keyValue)%26;
    for (int j=0; j<=25; j++){
      if (charValue == j)
        textFinal += alphabet[j];
    }
  }
  cout << "Final " << textFinal << endl;

  return textFinal;
}

Кто-нибудь может помочь?


person StudentEngineer    schedule 29.03.2015    source источник
comment
Вы не можете сравнивать std::string с одним char.   -  person πάντα ῥεῖ    schedule 30.03.2015
comment
(обязательная ссылка)   -  person chris    schedule 30.03.2015
comment
Что ты имеешь в виду? У меня нет ничего типа char. Я сравниваю одну букву в строке с одной буквой в массиве.   -  person StudentEngineer    schedule 30.03.2015
comment
@MichaelDaugherty Я сравниваю одну букву в строке с одной буквой в массиве. Вы не сравниваете. Дважды проверьте это!   -  person πάντα ῥεῖ    schedule 30.03.2015
comment
Первое, что я заметил, это цикл for, который, возможно, был нужен: for (int i = 0; i < 26; i++) {   -  person Evan Carslake    schedule 30.03.2015
comment
@MichaelDauherty string alphabet[26] — это 26 полных строк. Используйте string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";   -  person deviantfan    schedule 30.03.2015
comment
Я перебираю строку textInit и проверяю, соответствует ли textInit[i] каждому термину в алфавите. Моя итерация по строке неверна?   -  person StudentEngineer    schedule 30.03.2015
comment
@MichaelDaugherty Цикл по textInit не является неправильным, но переменная Alphabet ошибочна.   -  person deviantfan    schedule 30.03.2015
comment
@MichaelDaugherty Ваше представление о том, что составляет одну букву, неверно.   -  person πάντα ῥεῖ    schedule 30.03.2015
comment
@Michael: У вас есть что-то типа char: textInit[i].   -  person    schedule 30.03.2015
comment
Аааа, теперь я понял! Спасибо вам, ребята! Оно работает!   -  person StudentEngineer    schedule 30.03.2015


Ответы (4)


Вероятно, вы хотели объявить alphabet как

string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

чтобы избавиться от этого сообщения об ошибке.

Как упоминалось в комментарии, вместо этого вы объявили массив из 26 полноценных string, но индексирование из textInit[i] фактически возвращает вам тип char (который, в свою очередь, нельзя сравнивать с std::string).

person πάντα ῥεῖ    schedule 29.03.2015
comment
Или еще лучше, static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - person Ben Voigt; 30.03.2015
comment
Хорошая точка зрения. Но на этом этапе я хотел бы еще больше не запутать ОП. - person πάντα ῥεῖ; 30.03.2015
comment
Все в порядке, теперь я понимаю! Я полностью упустил твою мысль πάντα ῥεῖ - person StudentEngineer; 30.03.2015

Ошибка означает, что вы пытаетесь сравнить два разных типа, и для этих двух типов нет определенного оператора равенства.

Вы упомянули, что эта строка, в частности, виновата:

if (textInit[i] == alphabet[j])

Что такое тип textInit и тип алфавита? Посмотрите на свои декларации:

// textInit is a string
string textInit = m_text;

// alphabet is an array of strings
string alphabet[26] ={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","\
O","P","Q","R","S","T","U","V","W","X","Y","Z"}; 

Индексация в строку типа textInit возвращает char& (ссылку на символ). Индексирование массива строк, например алфавит, возвращает строку.

Итак, когда вы сравниваете textInit[i] с алфавитом[j]), вы пытаетесь сравнить строку с char&. Не существует определенного способа их сравнения, поэтому программа не компилируется.

Как уже упоминалось, одним из быстрых исправлений является изменение объявления алфавитов на:

// note that single quotes ('') are used for characters while double quotes "" are used for strings
char alphabet[26] ={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

Теперь Alphabet представляет собой массив символов, а индексация в алфавит возвращает char (символ). Итак, строка:

if (textInit[i] == alphabet[j])

теперь все в порядке, потому что вы сравниваете char с char&, и типы совместимы.

person Will Resond    schedule 29.03.2015

Причина ошибки в том, что типы textInit[i] и Alphabet[j] не совпадают. Вы можете изменить строковый алфавит[26] на символьный алфавит[26].

person John    schedule 29.03.2015
comment
Вы можете изменить строковый алфавит[26] на символьный алфавит[26]. Не без изменения инициализации. - person πάντα ῥεῖ; 30.03.2015

Эти другие ответы действительно решают вашу проблему, но есть другое решение: вместо повторения алфавита вы можете выполнить эту проверку за постоянное время, используя природу типа char. Символы — это просто целые числа, а буквы (данного регистра) гарантированно идут последовательно. Таким образом, вы можете заменить первый цикл следующим образом:

if (textInit[i] >= 'A' && textInit[i] <= 'Z') {
    charValue = textInit[i] - 'A';
}

И этот второй цикл также не нужен. Можно просто так:

textFinal += (charValue + 'A');
person ahruss    schedule 29.03.2015