strcmp игнорирует акценты, выводит false

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

if(strcmp(arrayOfStrings[index], "Día de descanso") == 0

Выводит false вместо true. Я пытался сравнить с помощью escape-последовательностей, но не могу заставить его работать.

Строки добавляются в arrayOfStrings с помощью следующей функции:

void introducirPlan()
{
  for(int i = 1; i <= 10; i++)
  {
    printf("Actividad del dia %d? ", i);
    scanf(" %[^\n]", diasEntrenamiento[i]);
  }
  printf("\n");
}

Есть еще одна функция для проверки строк, добавленных с помощью strcmp:

bool compararDescanso(int idia)
{
  if(strcmp(diasEntrenamiento[idia], "Día de descanso") == 0)
  {
    return true;
  }
  if(strcmp(diasEntrenamiento[idia], "Dia de descanso") == 0)
  {
    return true;
  }
}

Похоже, что здесь strcmp выводит false:

  while(cntImprEntr <= 10)
  {
    if(compararDescanso(cntImprEntr) == true)
    {
      printf(" D "); /*"D" never gets printed if string contains accent */
      columna++;
      dia++;
    }
    else
    {
      printf(" C ");
      columna++;
      dia++;
    }
    if(columna == 5)
    {
      printf("|");
    }
    printf(" ");
    cntImprEntr++;
    if(columna >= 7)
    {
      printf("\n");
      columna = 0;
    }
  }

Есть ли способ заставить strcmp не игнорировать акцент и выдавать истинный вывод? Когда строка внутри индекса содержит «Dia» вместо «Día», все работает нормально. Спасибо


person jgam    schedule 15.01.2018    source источник
comment
Попробуйте строки юникода.   -  person Gaurav Sehgal    schedule 15.01.2018
comment
требуется минимальный воспроизводимый пример. Мы не знаем, что содержит ваш массив.   -  person Eugene Sh.    schedule 15.01.2018
comment
Дело в том, что когда сравниваемая строка точно соответствует Día, как указано выше, strcmp все равно выводит false. Остальная часть массива содержит случайные строки.   -  person jgam    schedule 15.01.2018
comment
Нам нужно, чтобы это было доказано с помощью минимально воспроизводимого примера, как уже было задано. Без этого вопрос скоро закроется.   -  person Eugene Sh.    schedule 15.01.2018
comment
@jgam Дело в том, что проблема может быть в самой строке, которую вы сохранили в `arrayOfStrings[index], не могли бы вы подготовить mcve: stackoverflow. com/help/mcve   -  person Vagish    schedule 15.01.2018
comment
Я добавил больше деталей, чтобы помочь понять всю ситуацию.   -  person jgam    schedule 15.01.2018
comment
Вы не показали побайтовые дампы двух строк, что является единственным способом продемонстрировать, какой результат должен возвращать strcmp(). Существуют разные способы представления символов с диакритическими знаками в UTF-8 — иногда как один составной символ (одна кодовая точка), иногда как базовый символ с акцентом в качестве модификатора (с использованием двух кодовых точек). Две такие строки, показывающие один и тот же глиф, не будут сравниваться равными. Вы также должны знать, в каком кодовом наборе вы работаете. Но хорошим началом будет недвусмысленный дамп двух строк, которые, по вашему мнению, должны быть равны.   -  person Jonathan Leffler    schedule 15.01.2018
comment
минимальный воспроизводимый пример может быть недостаточным сам по себе, поскольку есть другие факторы, такие как источник и выполнение кодировки символов программы и кодировки символов пользовательского ввода программы. Кодировками исходных и исполняемых символов можно управлять с помощью параметров компилятора. Для GCC это будет опция -finput-charset= (для кодировки символов исходного кода) и опция -fexec-charset= (для кодировки исполняемых символов). Вам также может понадобиться настроить терминал на правильную локаль и вызвать setlocale, хотя strcmp не заботится о локали.   -  person Ian Abbott    schedule 15.01.2018


Ответы (1)


Ваша проблема связана с кодировкой текста.

Хотя вы этого не говорите, вы, вероятно, работаете в Windows и используете терминал для своей программы.

Проблема в том, что Windows использует другую кодировку символов для вашего терминала, чем для «оконных» программ (и, следовательно, вашего текстового редактора).

Это означает, что код для акцентированных символов одинаков.

Прежде всего, нужно понять, что такое кодировки Unicode и charcater: знать-о-юникоде-и-наборах-символов-без-извинений/" rel="nofollow noreferrer">https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software- разработчик-абсолютно-положительно-должен-знать-о-юникоде-и-наборах-символов-без-оправданий/

Во-вторых, просто измените кодировку вашего текстового редактора, чтобы она соответствовала кодировке терминала — я не уверен, что кодировка, используемая для Windows на испанском языке, но на португальском языке, это cp-852 для терминала и latin1 для «оконный» (я Могу поспорить, что это «latin1» и для испанской Windows).

NB.> В то время как Microsoft застряла с этими кодировками с 1980-х годов, остальной мир, включая весь Интернет, использует «utf-8». Таким образом, этот обходной путь кодирования хорош для работы вашего кода, и вы учитесь на нем, но вам обязательно следует сосредоточиться на использовании кодировки «utf-8» для любой вещи, которой суждено действительно быть в производстве.

person jsbueno    schedule 15.01.2018