Почему в коде программирования для преобразования нижнего регистра в верхний регистр мы используем (str[i]›=97 && str[i]‹=122)?

Итак, это программа, которую я использовал для преобразования нижнего регистра в верхний. Можете ли вы сказать мне, почему мы используем эту штуку?[(str[i]>=97 && str[i]‹=122)] в следующем раздел кода?

#include <iostream.h>
#include <conio.h>
#include <string.h>
void main()
{
    clrscr();
    char str[20];
    int i;
    cout << "Enter the String (Enter First Name) : ";
    cin >> str;
    for (i = 0; i <= strlen(str); i++) {
        if (str[i] >= 97 && str[i] <= 122) //Why do we use this???
        {
            str[i] = str[i] - 32;
        }
    }
    cout << "\nThe String in Uppercase = " << str;
    getch();
}

person Veritasium    schedule 31.01.2017    source источник
comment
Вам может помочь таблица ASCII.   -  person Some programmer dude    schedule 31.01.2017
comment
97 — это ASCII-код 'a', 122 — это ASCII-код 'z'. Все символы между ними (и включая их) обычно называются строчными буквами, не так ли?   -  person axiac    schedule 31.01.2017
comment
И, пожалуйста, не учитесь ничему из этой программы, она ужасна. Он использует магические числа, которых следует избегать. Не использует прекрасную функцию std::toupper. Он использует кодировку ASCII и поэтому не является переносимым. И он не использует std::string и подвержен переполнению буфера.   -  person Some programmer dude    schedule 31.01.2017
comment
Кроме того, #include<string.h> устарел с 90-х годов, а #include<iostream.h>, а также void main никогда не были законным стандартом C++. Вы должны получить лучший и более современный код, чтобы учиться.   -  person Baum mit Augen    schedule 31.01.2017
comment
if(str[i]›=97 && str[i]‹=122) //Почему мы это используем??? Обычно мы используем (если нам действительно нужно это, что в современном C++ встречается редко) if(str[i]>='a' && str[i]<='z'), так как это намного читабельнее.   -  person Algirdas Preidžius    schedule 31.01.2017
comment
@AlgirdasPreidžius, если я использую if(str[i]›='a' && str[i]‹='z'), то выскакивает ошибка типа ~невозможно преобразовать char в char*   -  person Veritasium    schedule 31.01.2017
comment
@Veritasian Я не понимаю, как это возможно. Вы случайно не использовали двойные кавычки (") вместо одинарных (')?   -  person Algirdas Preidžius    schedule 31.01.2017
comment
@Veritasian Тем не менее, вы публикуете правильный код в комментарии. Интересно.   -  person LogicStuff    schedule 31.01.2017
comment
** if(str[i]›=a && str[i]‹=z) { str[i]=str[i]-32; } @AlgirdasPreidžius это то, что я сделал   -  person Veritasium    schedule 31.01.2017
comment
Это неправильно, потому что вы использовали " вместо ' " используется для строк. ' используется для обозначения персонажа.   -  person drescherjm    schedule 31.01.2017
comment
@Veritasian Тогда вы не использовали мой пример. Посмотрите еще раз.   -  person Algirdas Preidžius    schedule 31.01.2017
comment
@AlgirdasPreidžius Теперь я получил код!!! Спасибо всем :)   -  person Veritasium    schedule 31.01.2017
comment
@AlgirdasPreidžius: if(str[i]>='a' && str[i]<='z') все еще не переносим. Этот трюк действительно работает для чисел от '0' до '9', потому что C++ специально гарантирует последовательное числовое представление цифр, но не букв.   -  person Christian Hackl    schedule 31.01.2017
comment
@ChristianHackl Да, я знаю это. Моя точка зрения заключалась в том, что это намного более читабельно (и намерение намного яснее), чем исходная версия OP, с использованием магических чисел.   -  person Algirdas Preidžius    schedule 31.01.2017
comment
Даже если он написан переносимым кодом, этот алгоритм не подходит для преобразования символов в верхний регистр. Правила регистра зависят от системы письма и языка (см. setlocale()). (Даже если ваш проблемный домен имеет только английский текст, там используется больше буквенных символов, чем az и AZ.) Вот почему существуют библиотеки.   -  person Tom Blodget    schedule 31.01.2017


Ответы (5)


Эта часть кода написана очень плохо:

if(str[i]>=97 && str[i]<=122)
{
 str[i]=str[i]-32;
}

Это было бы намного более переносимым и более читаемым, как:

if(str[i]>='a' && str[i]<='z')
{
 str[i]=str[i]-'a'+'A';
}

или, что еще лучше, используйте стандартные макросы/функции библиотеки C (из <ctype.h>):

if(islower(str[i]))
{
 str[i]=toupper((unsigned char)str[i]);
}

или еще лучше, вы можете просто полностью пропустить тест и написать:

str[i]=toupper((unsigned char)str[i]);

(поскольку toupper вернет символ без изменений, если это не строчная буква).

person Paul R    schedule 31.01.2017
comment
Еще лучше было бы просто сказать str[i] = toupper((unsigned char)str[i]). - person John Zwinck; 31.01.2017
comment
@JohnZwinck: да, спасибо, все еще работаю над уточнением ответа... ;-) - person Paul R; 31.01.2017
comment
читабельнее конечно. да, намного более переносимым, но все же не полностью, потому что нет гарантии, что от 'a' до 'z' будут иметь последовательные числовые представления. - person Christian Hackl; 31.01.2017
comment
@ChristianHackl: правда, исходная реализация и моя первая версия не подходят для EBCDIC, поэтому дальнейшие улучшения с использованием <ctype.h> я дал ниже в ответе. - person Paul R; 31.01.2017
comment
toupper() без приведения к unsigned char может привести к неопределенному поведению, если встречается отрицательный символ. - person John Zwinck; 01.02.2017
comment
@JohnZwinck: хороший момент - нужно убедиться, что мы правильно обрабатываем расширенный ASCII и другие. - person Paul R; 01.02.2017

97 — это десятичное представление символа ascii a, а 122 — это z.

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

Обратите внимание, что в этом случае запись str[i] <= 122 или str[i] <= 'z' эквивалентна.

таблица ascii

person Derlin    schedule 31.01.2017
comment
@axiac: Когда вы в последний раз проверяли? Возможно, они изменили его. - person Benjamin Lindley; 31.01.2017
comment
@BenjaminLindley 5 минут назад :-) - person axiac; 31.01.2017
comment
Обратите внимание, что в языке C str[i] ‹= 122 и str[i] ‹= 'z' эквивалентны. Нет, это не так. 'z' может быть или не быть 122. На практике вы можете никогда не встретить систему, в которой это не 122, но это не гарантируется. См. stackoverflow.com/a/29381142/3313064. - person Christian Hackl; 31.01.2017

Это было бы более подходящим кодом:

if(str[i]>='a' && str[i]<='z')
 {
 str[i]=str[i] + 'A' - 'a';
 }
}

Никаких цифр, и если буква находится между строчной «а» и строчной «z», она транспонируется за счет разницы между «А» и «а» и, таким образом, становится ее версией в верхнем регистре.

person coyotte508    schedule 31.01.2017

Это характерно для ASCII, где строчные буквы имеют числовые значения 97-122. Это полезное свойство состоит в том, что символы верхнего регистра (которые отображаются от 65 до 90) могут быть преобразованы в нижний регистр с постоянным вычитанием или побитовой операцией (и наоборот).

Однако вообще неправильно предполагать, что каждая существующая система использует ASCII; есть и другие наборы символов. Вы должны использовать библиотечные функции toupper и tolower из заголовка <cctype>.

person Govind Parmar    schedule 31.01.2017

Потому что это диапазон символов нижнего регистра в ASCII.

person Rob K    schedule 31.01.2017