Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
Troo
1 / 1 / 0
Регистрация: 09.10.2013
Сообщений: 73
#1

Перевод строк в верхний и нижний регистры не работает для кириллицы - C++

07.01.2014, 20:49. Просмотров 1319. Ответов 9
Метки нет (Все метки)

Для того, чтобы в программе можно было осуществлять различные действия вне
зависимости от регистра, используются специальные функции tolower(c) и
toupper(c), переводящие переданный им символ с в нижний и верхний регистр со-
ответственно. Однако эти функции работают лишь для букв латинского алфавита.
Напишите аналогичные функции, работающие с кириллицей.


не правильно работает

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<iostream>
#include <string>
#include<math.h>
#include<windows.h>
#include<string.h>
#include<stdio.h>
 
using namespace std;
 
char bufRus[256];
 
char* Rus(const char* text) {
      CharToOem(text, bufRus);
      return bufRus;
      }
char* Rtolower (char *s);
char* Rtoupper (char *s);
 
 
int main()
{
    char s[40];
    cin.getline(s,40);
    cout << '\n';
    cout << Rtolower(s) <<endl;
    cout << Rtoupper(s) <<endl;
    return 0;
}
char* Rtolower (char *s)
{
    for (int i=0;i<strlen(s);i++)
    if (s[i]<-32 && s[i]>-65) s[i]=s[i]+32;
    return s;
}
char* Rtoupper (char *s)
{
    for (int i=0;i<strlen(s);i++)
    if (s[i]<0 && s[i]>-33) s[i]=s[i]-32;
    return s;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2014, 20:49
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Перевод строк в верхний и нижний регистры не работает для кириллицы (C++):

Перевод символов в верхний/нижний регистры - C++
Ребят. Подскажите как прописать функцию. Для перевода букв a. toLower – перевод буквы в нижний регистр b. toUpper – перевод буквы...

Кроссплатформенный перевод русских букв в верхний/нижний регистр - C++
Добрый день. В прикрепленном топике описываются способы вывода русских букв на консоль. Но они почти все подвязаны под винду. Более...

Верхний и нижний регистр - C++
Напишите программу, которая читает клавиатурный ввод до символа @ и повторяет его, за исключением десятичных цифр, преобразуя каждую...

Строки в С++. Верхний и нижний регистр - C++
char alphabet; int i; char letter; for(letter='A',i=0;letter&lt;='Z'; letter++,i++) alphabet=letter; alphabet=NULL;...

Верхний и нижний регистр буквы - C++
#include &lt;cctype&gt; #include &lt;iostream&gt; int main() { using namespace std; char ch; while(cin.get(ch) &amp;&amp; ch !=...

Преобразование строки сначала в верхний регистр, потом в нижний - C++
Напишите программу, которая преобразовывает все символы введенной строки сначала в верхний регистр затем в нижний регистр а затем заменяет...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
TrueBit
95 / 95 / 12
Регистрация: 19.11.2012
Сообщений: 195
07.01.2014, 21:56 #2
У меня ваш код не работает(Visual Studio 2008):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<iostream>
using namespace std;
 
 
char* Rtolower (char *s);
char* Rtoupper (char *s);
 
 
int main() {
    char s[40];
    cin.getline(s,40);
    cout << '\n';
    
    cout << Rtolower(s) <<endl;
    cout << Rtoupper(s) <<endl;
    return 0;
}
char* Rtolower (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if (-128<=s[i] && s[i]<=-113) // rus1
            s[i]+=32;
        else if(-112<=s[i] && s[i]<=-97) // rus2
            s[i]+=80;
        else if(65<=s[i] && s[i]<=90) // en
            s[i]+=32;
    return s;
}
char* Rtoupper (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if ((-128+32)<=s[i] && s[i]<=(-113+32)) // rus1
            s[i]-=32;
        else if((-112+80)<=s[i] && s[i]<=(-97+80)) // rus2
            s[i]-=80;
        else if((65+32)<=s[i] && s[i]<=(90+32)) // en
            s[i]-=32;
    return s;
}
1
Убежденный
Системный программист
Эксперт С++
15550 / 7058 / 1114
Регистрация: 02.05.2013
Сообщений: 11,468
Завершенные тесты: 1
08.01.2014, 00:23 #3
Цитата Сообщение от Troo Посмотреть сообщение
Однако эти функции работают лишь для букв латинского алфавита.
Используйте toupper/tolower из <locale>.
Они выполняют преобразование регистра символов согласно заданной локализации.
0
alsav22
5419 / 4815 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.01.2014, 08:46 #4
C++
1
2
3
4
5
int main()
{
   SetConsoleCP(1251);
   SetConsoleOutputCP(1251);
...
В свойствах консоли выбрать шрифт Lucida Console
0
Troo
1 / 1 / 0
Регистрация: 09.10.2013
Сообщений: 73
08.01.2014, 18:10  [ТС] #5
TrueBit, а объясните пожалуйста почему именно такие функции

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
char* Rtolower (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if (-128<=s[i] && s[i]<=-113) // rus1
            s[i]+=32;
        else if(-112<=s[i] && s[i]<=-97) // rus2
            s[i]+=80;
        else if(65<=s[i] && s[i]<=90) // en
            s[i]+=32;
    return s;
}
char* Rtoupper (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if ((-128+32)<=s[i] && s[i]<=(-113+32)) // rus1
            s[i]-=32;
        else if((-112+80)<=s[i] && s[i]<=(-97+80)) // rus2
            s[i]-=80;
        else if((65+32)<=s[i] && s[i]<=(90+32)) // en
            s[i]-=32;
    return s;
}
0
MrGluck
Модератор
Эксперт CЭксперт С++
7239 / 4407 / 642
Регистрация: 29.11.2010
Сообщений: 11,927
08.01.2014, 18:18 #6
towlower, towupper

Добавлено через 43 секунды
Кстати, в линуксах работает и tolower, toupper.
0
TrueBit
95 / 95 / 12
Регистрация: 19.11.2012
Сообщений: 195
08.01.2014, 18:27 #7
Цитата Сообщение от Troo Посмотреть сообщение
TrueBit, а объясните пожалуйста почему именно такие функции

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
char* Rtolower (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if (-128<=s[i] && s[i]<=-113) // rus1
            s[i]+=32;
        else if(-112<=s[i] && s[i]<=-97) // rus2
            s[i]+=80;
        else if(65<=s[i] && s[i]<=90) // en
            s[i]+=32;
    return s;
}
char* Rtoupper (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if ((-128+32)<=s[i] && s[i]<=(-113+32)) // rus1
            s[i]-=32;
        else if((-112+80)<=s[i] && s[i]<=(-97+80)) // rus2
            s[i]-=80;
        else if((65+32)<=s[i] && s[i]<=(90+32)) // en
            s[i]-=32;
    return s;
}
исходя из значений 866 кодовой страницы ASCII кодов ( http://www.krles.ru/images/ad/ascii.pdf )

Вот можете по экспериментировать(если использовать без знаковый тип: unsigned char, то таблица будет полностью соответствовать, если знаковый то все символы после 127 будет начинаться с максимального отрицательного и до 0):

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream> 
#include <limits>
using namespace std;
 
int main() {
    /*for(int i=0; i<(int)numeric_limits<=unsigned char>::max(); i++)
        printf("[%3d] = %c\n",i,unsigned char(i));*/
    for(int i=numeric_limits<char>::min(); i<=(int)numeric_limits<char>::max(); i++)
        printf("[%3d] = %c\n",i,char(i));
}
кодовая таблица приложена к сообщению
0
Миниатюры
Перевод строк в верхний и нижний регистры не работает для кириллицы  
Troo
1 / 1 / 0
Регистрация: 09.10.2013
Сообщений: 73
08.01.2014, 18:35  [ТС] #8
TrueBit,
вот смотрю таблицу
http://cppstudio.com/uchebniki/yazyk...tablica-ascii/

не понимаю этих строк:
C++
1
2
3
4
if (-128<=s[i] && s[i]<=-113) // rus1
            s[i]+=32;
        else if(-112<=s[i] && s[i]<=-97) // rus2
            s[i]+=80;
C++
1
2
3
4
if ((-128+32)<=s[i] && s[i]<=(-113+32)) // rus1
            s[i]-=32;
        else if((-112+80)<=s[i] && s[i]<=(-97+80)) // rus2
            s[i]-=80;
Добавлено через 5 минут
TrueBit, Почему -113
0
TrueBit
95 / 95 / 12
Регистрация: 19.11.2012
Сообщений: 195
08.01.2014, 18:58 #9
Цитата Сообщение от Troo Посмотреть сообщение
Почему -113
Потому, что тип знаковый char(-113) тоже самое, что unsigned char(143). Войдите в калькулятор win+r calc. Вид-программист. Введите выберите размер 2 байта, введите 143 получится 10001111 бит последовательность, выберите размер 1 байт. Получится та же последовательность 10001111. Просто при использовании знакового типа старший разряд 1 байта используется под знак, а оставшиеся 7 бит используются под число. Поэтому число -113 знаковое и 143 без знаковое хранятся одинакого (таблицу для без знаковых можете посмотреть выше).

Вот переписал функцию, под без знаковый тип, чтобы она полностью соответствовала таблице кодов с диапазаном значений от 0 до 255

C++
1
2
3
4
5
6
7
8
9
10
11
char* Rtolower (char *s)
{
    for (int i=0;i<(int)strlen(s);i++)
        if (128<=(unsigned char)s[i] && (unsigned char)s[i]<=143) // если символ лежит в диапазан [128,143] - тоесть большие буквы
            s[i]+=32; // то переводим в другой диапазон [160,175] (маленькие буквы)
        else if(144<=(unsigned char)s[i] && (unsigned char)s[i]<=159) // тут вторая часть больших букв, потому, что продолжение(вторая половина)
            s[i]+=80; // маленьких букв находится чуть дальше, через 80 символов от больших
        else if(65<=s[i] && s[i]<=90) // en
            s[i]+=32;
    return s;
}
Добавлено через 12 минут
То есть если рассматривать эти 8 бит как знаковые числа(от -128 до 127), то один бит для знака(1000 0000 либо 1000 0000), остальные под число(от 000 0000 до 111 1111 ). Если рассматривать как без знаковый(от 0 до 255), то отрицательных нет и все первые 127 положительных чисел одинаковые ( 0111 1111 = 127 максимальное положительное знаковое, 0111 1111 = 127 положительное без знаковое). А дальше ( 1000 0000 - тут начинается отрицательные знаковые, а тут 1000 000 - следующее положительное без знаковое). Но с точки зрения символа это одно и то же.
1
Troo
1 / 1 / 0
Регистрация: 09.10.2013
Сообщений: 73
08.01.2014, 18:58  [ТС] #10
TrueBit, спасибо большое
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2014, 18:58
Привет! Вот еще темы с ответами:

Перевод в нижний регистр - C++
Приветствую . Прошу помощи , выдаёт ошибку при переводе в нижний регистр , в чём проблема ? #include &lt;vector&gt; #include &lt;fstream&gt; ...

Перевод в нижний регистр - C++
Есть строка стринг в которой записана кириллица, нужно перевести ее в нижний регистр.

Перевод с кириллицы на русский - C++
Доброго времени суток! Кто-нибудь подскажет, что здесь не так? Цель задачи - переводить cout с кириллицы на русский язык. Использую MS...

Перевод символа в нижний регистр - C++
Привет всем)) у меня такой вопрос: почему функция tolower() возвращает не символ в нижнем регистре, а какие-то цифры (наверное код буквы)....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
08.01.2014, 18:58
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru