Перегрузка метода std :: codecvt :: do_in против остальных базовых методов

Я перегружен do_in метод std::codecvt:

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

class codecvt_to_upper : public std::codecvt<char, char, std::mbstate_t> {
public:

explicit codecvt_to_upper(size_t r = 0) : std::codecvt<char, char,
std::mbstate_t>(r) {}
protected:
result do_in(state_type& state, const extern_type* from,
const extern_type* from_end, const extern_type*& from_next,
intern_type* to, intern_type* to_end, intern_type*& to_next)
const;

result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const {
return codecvt_to_upper::ok;
}

result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const {
return codecvt_to_upper::ok;
}

int
do_encoding() const throw () {
return 1;
}

bool
do_always_noconv() const throw () {
return false;
}

int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const {
return 1;
}

int
do_max_length() const throw () {
return 10;
}
};

codecvt_to_upper::result codecvt_to_upper::do_in(state_type& state,
const extern_type* from, const extern_type* from_end, const
extern_type*& from_next, intern_type* to, intern_type*
to_end, intern_type*& to_next) const {
codecvt_to_upper::result res = codecvt_to_upper::error;
const std::ctype<char>& ct = std::use_facet<std::ctype<char> >(
std::locale());

const extern_type* p = from;
while( p != from_end && to != to_end) {
*to++ = ct.toupper( *p++);
}
from_next = p;
to_next = to;
res = codecvt_to_upper::ok;
return res;
}

и использовал этот способ:

int main(int argc, char** argv) {

std::locale ulocale( std::locale(), new codecvt_to_upper);

std::cin.imbue( ulocale);

char ch;
while ( std::cin >> ch) {
std::cout << ch;
}
return 0;
}

но do_in перегрузка не вызывается. Я правильно перегрузил? Какой метод std::codecvt<char, char, std::mbstate_t> (и как) я должен изменить сделать мой вызов do_in метод?

0

Решение

Я думаю, что первое, что следует рассмотреть, это то, что std::codecvt семейные грани используются только std::basic_filebuf потому что преобразование кода необходимо только при работе с внешним устройством. В вашем коде вы вводили язык в std::cin, который имеет буфер, который делает не сделать преобразование кода.

Конечно, все еще возможно выполнить преобразование кода в программе, но вещь, которая мешала вашему коду работать, заключалась в том, что он унаследован от специализации std::codecvt<> это не может сделать преобразования. char => char специализация std::codecvt<> не определяет конверсию, поэтому do_in() не будет вызван, потому что нет необходимости конвертировать между двумя типами.

Я попытался запустить ваш код, но изменил унаследованный фасет на std::codecvt<wchar_t, char, std::mbstate> и использовали широкие символьные файловые потоки и это сработало.

Если вы хотите, чтобы это работало и для узкополосных потоков, я бы предложил создать буфер потока, который пересылает заглавные символы через underflow(),

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]