Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> strstr, utf8 
V
    Опции темы
korian
Дата 26.3.2008, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



а такая функция есть? - mblen
PM   Вверх
chubaka
Дата 26.3.2008, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 8.6.2007

Репутация: нет
Всего: нет



Да. Попробую с ней

Это сообщение отредактировал(а) chubaka - 26.3.2008, 14:12
PM MAIL   Вверх
marcusmae
Дата 26.3.2008, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Цитата(chubaka @  26.3.2008,  07:01 Найти цитируемый пост)
Как можна решить задачу максимально просто ?


Имхо, максимально просто - это прекратить рассматривать мультибайтовые чары и перейти к их представлению, как указатели на байтовые массивы. Сначала нам нужна функция, которая будет в массиве байт находить по эталону два последовательных байта (два байта - это, по определению, представление для кириллицы в utf-8).

Код

// Get the source string UTF-8 2-byte octet first occurence index.
int IndexOfCyr(char* source, const unsigned int sourceLength,
               char first, char second) {

    for (unsigned int index = 0; index < sourceLength - 1; index++)
        if ((source[index] == first) && (source[index+1] == second))
            return index;
    return -1;
}


Далее, нужна функция, которая будет в массиве байт находить эталонную последовательность пар байт.

Код

// Get the source string UTF-8 2-byte octets sequence first occurence index.
int IndexOfCyr(char* source, const unsigned int sourceLength,
               char* word, const unsigned int wordLength) {

    int index = IndexOfCyr(source, sourceLength, *word, *(word + 1));
    
    if (wordLength == 2) return index;

    while ((index != - 1) && (sourceLength - index >= wordLength - 2))
    {
        if (memcmp((const void*)(source + index + 2), (const void*)(word + 2),
            wordLength - 2) == 0) return index;

        index++;
        index = IndexOfCyr(source + index, sourceLength - index, *word, *(word + 1));
    }
    return -1;
}


Ключевая функция - memcmp - сравнение байтовых последовательностей.

Для проверки, строки я ввожу из файлов в формате UTF-8 :

string.txt
Цитата

The quick коричневая лисица jumps over the lazy dog


substring.txt
Цитата

коричневая лисица


Файлы - в UTF-8, но читаю, как байты :

Код

// Load byte array from the file with the specified name.
char* LoadBytes(const char* filename, int* size) {

    // Get the file size in bytes.
    struct _stat filestat;
    _stat(filename, &filestat);

    // Open file, alloc array, read bytes and close file.
    ifstream file(filename, ios_base::binary | ios_base::in);
    char* fileStream = new char[filestat.st_size];
    file.read(fileStream, filestat.st_size);
    file.close();

    *size = filestat.st_size;

    return fileStream;
}


В результате, для приведённых файлов

Код

int _tmain(int argc, _TCHAR* argv[])
{
    const int utfHeaderOffset = 3;

    int
        stringSize,
        substringSize;

    char
        *string = LoadBytes("string.txt", &stringSize),
        *substring = LoadBytes("substring.txt", &substringSize);

    cout << IndexOfCyr(string + utfHeaderOffset, stringSize - utfHeaderOffset,
        substring + utfHeaderOffset, substringSize - utfHeaderOffset);

    delete string, substring;

    cin.get();

    return 0;
}


ответом является
Цитата

10


то есть, коричневая лисица началась с десятой позиции в строке.

В примечание - utfHeaderOffset - некий маркер utf-формата, который можно отладчиком увидеть в обоих строках. Мы должны его перепрыгнуть, иначе совпадений не будет найдено (-1).

Вроде не очень сложно, да?..

Это сообщение отредактировал(а) marcusmae - 26.3.2008, 15:18

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  CyrUTF8.rar 179,63 Kb


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
chubaka
Дата 27.3.2008, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 8.6.2007

Репутация: нет
Всего: нет



marcusmae, спасибо огромное за такой полный ответ, но мне не помогло.
Исходная задача такая: есть 2 std::string обьекта. Они не загружаются из файла. Они через сокеты получают данные от другого сервера. Отсюда видимо значит что и маркера UTF формата не будет. 

 smile 

Это сообщение отредактировал(а) chubaka - 27.3.2008, 09:00
PM MAIL   Вверх
korian
Дата 27.3.2008, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(chubaka @  27.3.2008,  07:59 Найти цитируемый пост)
Отсюда видимо значит что и маркера UTF формата не будет.

про маркеры никто ничего не говорил.
короче я так понимаю, что проблема у вас в том, что вы или не знаете форматов сравниваемых строк, или не правильно их задаете.
поясните от куда берется строка limit_string и как задается search_for. и в каком они формате и уверены ли вы, что они в этом формате.

Это сообщение отредактировал(а) korian - 27.3.2008, 09:38
PM   Вверх
chubaka
Дата 27.3.2008, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 8.6.2007

Репутация: нет
Всего: нет



korian, про маркеры писал ув. marcusmae.

limit_string - HTML страница, полученная CURL'ом.
search_for - данные из файла, для поиска в коде HTML страницы. Загружается ifstream'ом. 
PM MAIL   Вверх
korian
Дата 27.3.2008, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 8.3.2008
Где: Украина, Харьков

Репутация: 3
Всего: 17



Цитата(chubaka @  27.3.2008,  08:45 Найти цитируемый пост)
korian, про маркеры писал ув. marcusmae.

он писал что его надо перепрыгнуть, т.к. он нам нафиг не нужен, т.к. мы из начально знаем что там UTF-8. а по стандарту он туда пишется.
если файл из которого читается search_for - UTF-8
и search_for - это std::string, а ifstream - это std::ifstream, и читается оно по типу ifstream.getline(search_for), то у вас из начально не правильные значение в search_for.

Это сообщение отредактировал(а) korian - 27.3.2008, 09:59
PM   Вверх
Rififi
Дата 27.3.2008, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 11
Всего: 36



chubaka, 
C/C++ рантайм не поддерживает работу с utf-8.
поэтому перед использованием текст надо перекодировать в честный utf-16 и юзать W-функции
см. MultiByteToWideChar
PM MAIL   Вверх
chubaka
Дата 27.3.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 8.6.2007

Репутация: нет
Всего: нет



korian, уважаемый, вы гений =) Огромное спасибо. Действительна проблема была в том, что я неверно вводил данные в файл. Я программирую на удаленном сервере через SSH, и клиент PuTTy неверно принимал русские символы. Спасибо большое !

Также спасибо большое всем кто старался помочь. Много полезных советов на будущее  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0850 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.