Сравнение двух массивов на C без учета регистра

#arrays #c

#массивы #c

Вопрос:

У меня есть, например, два массива

символ 1 равен: 77a abcd Abc abc1d @#@# v k

char2 равен: 789 ABA AABB 123 ab #% abcde

Общий индекс должен быть в местах 0,3,4,5,9,10,12,20

Результат должен быть 8, но я получаю 9 Проблема в том, что код Aski ниже 64 все еще работает, и он не должен быть кодом

 int intersection(char arrayNumberOne[size], char arrayNumberTwo[size])
{
    int counter = 0;

    for (int i = 0; i < strlen(arrayNumberOne); i  )
    {
        if ((arrayNumberOne[i] == arrayNumberTwo[i]) || (arrayNumberOne[i] == arrayNumberTwo[i]   32) || (arrayNumberOne[i]   32 == arrayNumberTwo[i]))
        {
            if (arrayNumberOne[i] < 64)
            {
                ?????
            }
            
            
                counter  ;
            
        }
    }
    return counter;
}
 

Комментарии:

1. Используйте tolower (или toupper ) для каждого элемента перед сравнением.

2. Является ли целью сравнение строк или массивов символов?

3. массивы символов, которые мне нужны

4. Что такое магическое число 64 ?

5. Вы возитесь с буквенными кодами ASCII. Гораздо лучше следовать совету @EugeneSh. и использовать toupper or tolower . Посмотрите на его документы . Он будет использовать прописные буквы или исходный символ, если это не буква. Используйте его в обоих элементах сравнения.

Ответ №1:

Суммирование 32 с символом ASCII может привести к нежелательным комбинациям, и вы уже обнаружили проблему.

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

Во-первых, условие о символах является неполным, затем измените:

if (arrayNumberOne[i] < 64)

Для:

if (arrayNumberOne[i] <= 64 || arrayNumberTwo[i] <= 64)

Потому что оба массива могут содержать символ.

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

 // considering inside a for-loop used 'continue' to skip the other verifications

// compare any character
// both lower case or upper case
if (arrayNumberOne[i] == arrayNumberTwo[i]) {
   counter  ;
   continue;
}

// is a symbol, skip the verification ahead
if (arrayNumberOne[i] <= 64 || arrayNumberTwo[i] <= 64)
   continue;

// character verifications

// first is uppercase
if (arrayNumberOne[i]   32 == arrayNumberTwo[i]) {
   counter  ;
   continue;
}

// second is uppercase
if (arrayNumberOne[i] == arrayNumberTwo[i]   32) {
   counter  ;
   continue;
}

 

Это заставит ваш код работать, но было бы лучше проверить наличие ‘a-z’ или использовать tolower, как они сказали в комментариях / ответах.

Ответ №2:

Используйте tolower, нет необходимости делать strlen, и вам нужно проверить длину обеих строк.

приведение к (unsigned char) этому позволяет избежать неопределенного поведения, если char является типом со знаком (что часто бывает) и если какой-либо из массивов содержит отрицательные значения char (которые отличаются от EOF: одно отрицательное значение, разрешенное в tolower) (спасибо @Kaz, чтобы отметить это)

 #include <ctype.h>
#include <stdio.h>


int intersection(const char *s1, const char *s2)
{
    int counter = 0;

    while (*s1 != '' amp;amp; *s2 != '') {
        if (tolower((unsigned char) *s1  ) == tolower((unsigned char) *s2  )) {
            counter  ;
        }
    }
    return counter;
}


int main() {
    printf("%dn", intersection("77a abcd Abc abc1d @#@# v k",
                                "789 ABA AABB 123 ab #% abcde"));
    return 0;
}
 

ВОЗВРАТ 8