Нужны русские варианты upper/lower
От: ShootNick  
Дата: 21.02.03 11:23
Оценка:
Привет!

Если так
setlocale(LC_ALL,"Russian_Russia.866")
toupper ( строка 866 русский алфавит )
то не работает

Если так
setlocale(LC_ALL,"Russian_Russia.1251")
toupper ( строка 1251 русский алфавит )
то работает

А у меня то программа как раз консольная. Мне надо 866.
А c 866 не работает.

Может кто-то написал функции toupper, tolower с поддержкой русских кодировок?
Поделитесь пожалуйста. Поиск по форуму облазил, интернет — не нашел. Нужно не только для прямого преобразования в upper/lower но и для использования в регистро-независимом поиске и т.п. Поделитесь пожалуйста. А то setlocale с 866 никак не работает Наверное что-то напутали они там со стандартами. Спасибо вам!
Re: Нужны русские варианты upper/lower
От: lozzy  
Дата: 21.02.03 14:48
Оценка: -2
SN>Может кто-то написал функции toupper, tolower с поддержкой русских кодировок?
Это... Если известны, минимальные и максимальные коды для прописных и заглавных буковок — то в чем проблема ? Это же 4 элементарные ф-ии... типа
bool isLower(char c);
char getLower(char c);
bool isUpper(char c);
char getLower(char c);


Если до сих пор смысл непонятен — я умываю руки
Re: Нужны русские варианты upper/lower
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 21.02.03 16:26
Оценка:
Здравствуйте, ShootNick, Вы писали:

SN>Может кто-то написал функции toupper, tolower с поддержкой русских кодировок?

SN>Поделитесь пожалуйста. Поиск по форуму облазил, интернет — не нашел. Нужно не только для прямого преобразования в upper/lower но и для использования в регистро-независимом поиске и т.п. Поделитесь пожалуйста. А то setlocale с 866 никак не работает Наверное что-то напутали они там со стандартами. Спасибо вам!

Вот тут сам решил немного разобраться в этом вопросе и набросал пару примеров.

#include <iostream>
#include <algorithm>
#include <string>
#include <locale>

struct uppercase
{
    uppercase(const std::locale& loc) :
        loc(loc)
    {}
    
    char operator()(const char &c)
    {
        return std::toupper(c, loc);
    }
    
private:
    std::locale loc;
};


int main()
{
    std::string s("строка 866 русский алфавит");
    std::locale loc("rus_rus.866");
    std::transform(s.begin(), s.end(), s.begin(), uppercase(loc));
    std::cout << s;
    
    return 0;
}


или без извращений :
#include <iostream>
#include <string>
#include <locale>

using namespace std;

void string_toupper(string &s, const locale &loc)
{
    for (string::iterator i=s.begin(), j=s.end(); i!=j; ++i)
        *i = toupper(*i, loc);
}

int main()
{
    string s("строка 866 русский алфавит");
    string_toupper(s, locale("rus_rus.866"));
    std::cout << s <<'\n';
    
    return 0;
}


Насчет регистро-независимого поиска тоже есть кое-что. Как оформлю в примерчик, положу.
... << RSDN@Home 1.0 beta 5 >>
Re[2]: Нужны русские варианты upper/lower
От: ShootNick  
Дата: 21.02.03 18:23
Оценка:
Здравствуйте, Михаил Можаев, Вы писали:

ММ>Вот тут сам решил немного разобраться в этом вопросе и набросал пару примеров.

Спасибо. Но я же говорю — locale у меня с кодировкой 866 не работает. Только с 1251.
Вот что я получил когда откомпилировал вашу программу:
"--+ока 866 ++--кий ал-аби-"
Символы '+' и '-' поставил Windows вместо псевдографики DOS. Вообщем upper не произошло.
Это при исходной кодировке 866. А если исходная 1251 — то все работает.
А мне надо 866.
А у вас все работает с 866 DOS кодировкой (если в ней исходная строка)?
Я использую Visual C++ v6.0.

ММ>Насчет регистро-независимого поиска тоже есть кое-что. Как оформлю в примерчик, положу.

Спасибо.

lozzy: Вот и кинул бы пример. Если это для тебя так просто.

Неужели ни у кого нет рабочего примера (для 866 кодировки)? Может из старых DOS времен.
Re[3]: Нужны русские варианты upper/lower
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 21.02.03 18:46
Оценка:
Здравствуйте, ShootNick, Вы писали:

SN>Неужели ни у кого нет рабочего примера (для 866 кодировки)? Может из старых DOS времен.


Вот именно, что пример у меня работает. Как раз в 866 кодировке. VC++ 6 SP5.

Попробуй явно указать везде std:: вместо using namespace std; Правда, не уверен, что поможет.
Где ты компилируешь программу? Я делал так: исходник (в 866 кодировке) компилю через
cl /GX prog.cpp

Запускаю из консоли и все вижу правильно.
... << RSDN@Home 1.0 beta 5 >>
Re[3]: Нужны русские варианты upper/lower
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 21.02.03 19:07
Оценка:
Здравствуйте, ShootNick, Вы писали:

SN>lozzy: Вот и кинул бы пример. Если это для тебя так просто.


Не надо думать, что все так уж просто. Полчаса полазить по докам, книгам и исходникам понадобилось.
А пример сравнения/поиска кину только после выходных. Пока же можешь почитать Guru Of The Week #29. Потом можешь адаптировать для локалей (только сначала надо, чтобы toupper заработал).

SN>Неужели ни у кого нет рабочего примера (для 866 кодировки)? Может из старых DOS времен.


Мой пример рабочий (по крайней мере, для меня). Думаю, что ты что-то не так делаешь или объясняешь...
... << RSDN@Home 1.0 beta 5 >>
Re: Нужны русские варианты upper/lower
От: adontz Грузия http://adontz.wordpress.com/
Дата: 22.02.03 11:34
Оценка: 3 (1)
Здравствуйте, ShootNick, Вы писали:

WinAPI
CharUpperBuff
CharLowerBuff

?

CharUpperBuff
The CharUpperBuff function converts lowercase characters in a buffer to uppercase characters. The function converts the characters in place.

DWORD CharUpperBuff(
LPTSTR lpsz, // characters
DWORD cchLength // number of characters to process
);
Parameters
lpsz
[in] Pointer to a buffer containing one or more characters to process.
cchLength
[in] Specifies the size, in TCHARs, of the buffer pointed to by lpsz. This refers to bytes for ANSI versions of the function or WCHARs for Unicode versions.
The function examines each character, and converts lowercase characters to uppercase characters. The function examines the number of characters indicated by cchLength, even if one or more characters are null characters.

Return Values
The return value is the number of TCHARs processed.

For example, if CharUpperBuff("Zenith of API Sets", 10) succeeds, the return value is 10.

Remarks
Note that CharUpperBuff always maps lowercase I to uppercase I, even when the current language is Turkish or Azeri.

Windows NT/2000/XP: To make the conversion, the function uses the language driver for the current language selected by the user at setup or by using Control Panel. If no language has been selected, the system completes the conversion by using internal default mapping. The conversion is made based on the code page associated with the process locale.

Windows 95/98/Me: The function makes the conversion based on the information associated with the user's default locale, which is the locale selected by the user at setup or by using Control Panel. The system does not have language drivers.

Windows 95/98/Me: CharUpperBuffW is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.

A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Нужны русские варианты upper/lower
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 22.02.03 15:03
Оценка:
Здравствуйте, ShootNick, Вы писали:

SN>Вот что я получил когда откомпилировал вашу программу:

Пример рабочий. Есть подозрение, что ты текст программы cd виндовой кодировке вбил. Если есть FAR, попроьбуй открыть редактор, щелкнуть F8, чтоб DOS стал кодировкой, и вставить текст.

VC6 без всех SP. Вот, кстати, вспомнил, что я забыл поставить
Алексей Кирдин
Re[4]: Нужны русские варианты upper/lower
От: Михаил Можаев Россия www.mozhay.chat.ru
Дата: 26.02.03 17:37
Оценка:
Здравствуйте, Михаил Можаев, Вы писали:

ММ>А пример сравнения/поиска кину только после выходных.


Вот и обещанный пример (сравнение):
#include <locale>
#include <string>
#include <iostream>

using namespace std;

bool ci_compare2(const string &s1, const string &s2, const locale &loc)
{
    for (string::const_iterator f1=s1.begin(), l1=s1.end(), f2=s2.begin(), l2=s2.end();
        f1!=l1 && f2!=l2; ++f1, ++f2)
        if (toupper(*f1, loc) != toupper(*f2, loc))
            return false;
    return (f1 == l1 && f2 == l2);
}

int main()
{
    if (ci_compare2("Русский текст", "РуСсКиЙ ТеКсТ", locale("rus_rus.866")))
        cout << "Success\n";
    else
        cout << "Fail\n";
        
    if (ci_compare2("Русский текчт", "РуСсКиЙ ТеКсТ", locale("rus_rus.866")))
        cout << "Success\n";
    else
        cout << "Fail\n";
        
    return 0;
}
... << RSDN@Home 1.0 beta 5 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.