Вот в линуксе не нашёл функцию strlwr, а чем её заменили? Или похожей функции совсем нету?
>Вот в линуксе не нашёл функцию strlwr, а чем её заменили? Или
>похожей функции совсем нету?Что делает эта ваша ф-ция? В гуле уже искали по словам "strlwr linux" ?
>>Вот в линуксе не нашёл функцию strlwr, а чем её заменили? Или
>>похожей функции совсем нету?
>
>Что делает эта ваша ф-ция? В гуле уже искали по словам "strlwr
>linux" ?Она переводит все семволы строки в нижний регистр. В гугле искал. Это сишная функция.
>Она переводит все семволы строки в нижний регистр.Стандартной нет. Придётся написать свою, благо это очень легко:
for (int i = 0; i < strlen(string); ++i) {
string[i] = tolower(string[i]);
}Если на С++, то можно transform()'ом пройтись или использовать to_lower() из буста.
ну или так если очень уж длинная...
for (char *p = str; *p; p++) *p = tolower(*p);кстати всем вопрос на засыпку: сколько раз вычисляется условие цикла ?
>for (char *p = str; *p; p++) *p = tolower(*p);
>кстати всем вопрос на засыпку: сколько раз вычисляется условие цикла ?strlen(str)+1
В чём "засыпка"-то??
>В чём "засыпка"-то??в 3 посте вроде
>>В чём "засыпка"-то??
>в 3 посте вродеСтупил. Не прочитал неотквоченное. |*)
>ну или так если очень уж длинная...
>for (char *p = str; *p; p++) *p = tolower(*p);
>
>кстати всем вопрос на засыпку: сколько раз вычисляется условие цикла ?Код был приведен для примера, ясень пень юзать strlen() в условии не гуд.
А ваще:
for (char *p = str; p && *p; ++p) *p = tolower(*p); // и то, только в c99 или С++, иначе char *p объявляется до цикла.
и т.д.Смысл примера был в другом.
А если уж хочется вопросов на засыпку, то:
1. смотрим man tolower(), на предмет возвращаемого значения =)
2. думаем что случится если кодировка в строке будет несколько не та.. не соответствовать локали так сказать..
3. ну и наконец utf-8, для которой это не работает ни разу. А если еще осознать что в utf-8 один и тот же символ в нижнем и верхнем регистре может быть представлен разным количеством байтов...
4. а еще бывает wide char... и юникод =)
повторяющееся определение strlwr есть в гугле. кстати сказать функции из string.h никогда не проверяли аргументы на NULL, на соответствие кодировки/локали и есть тама utf-8 или нет; определить это - задача программиста. для wchar_t будет соотв. wcslwr.
tolower вернул int, что и должен был. (??)
>повторяющееся определение strlwr есть в гугле.гугл это еще не posix.
>кстати сказать функции из string.h никогда
>не проверяли аргументы на NULL, на соответствие кодировки/локали и есть тама
>utf-8 или нет; определить это - задача программиста. для wchar_t будет
>соотв. wcslwr.Я продемонстрировал ненужность указания недочетов в примере, это всего лишь пример. На вашем же примере показав как минимум три недочета в коде. Проверять или не проверять на null в вашем примере тоже самое что писать в условии цикла strlen(), т.к. и то, и то плохой стиль. Задача программиста писать переносимый код, а не код который завтра же придется править только потому что у клиента другая кодировка. В случае введения поддержки utf-8 такой код править - полный абзац (по опыту), особенно для интернационального приложения.
>tolower вернул int, что и должен был. (??)
Да, именно так, и принимает int, а данные char. Функция небезопасная. Хотя в данном примере порча строки при некорректной локали это максимум что может произойти. Но все же были случаи когда это порождало серьезные баги.
простите, признаюсь что тупо напал на strlen.
вы меня не совсем поняли. я говорю о том, как на самом деле определена функция, пусть не posix'ом, то хотя бы большим количеством описаний в сети. прочитайте его еще раз. написана она в соотв. с теми требованиями, которые были к ней до этого, своего ничо не добавлял ;) т.о. задачу по реализации считаю выполненной правильно.если у клиента другая кодировка, то (раз уж мы работаем с содержимым строк как с символами, а не как с байтами туда-обратно) при "не той" кодировке "перестанет" работать и весь clib, так ? для выбора другой локали есть setlocale(), utf-8 же clib'ом поддерживается только через mbs->wcs, и функции работы с wcs имеют одноименный префикс. где уж это мой недочет ? если программист _действительно_ планирует работу с толстыми буквами, то ему нужно подумать об этом заранее, а не ругать имеющиеся средства. то есть конвертим utf8 в wcs и применяем wcslwr/towlower. с ucs4 конечно на clib'е тяжелее.
насчет локали. если setlocale() вызвана с верным аргументом, то для любой 8-битной кодировки tolower() вернет правильное значение, даже для utf8 (т.к. utf8 в плане однобайтных символов идентична 7-bit ascii, и ни одна русская буква не попортится). и разумеется *str*lwr не обратит неаскёвую часть.
избитый нами int tolower(int) принимает в нашем контексте всегда не более чем char; в мануале сказано, что если "c is not an unsigned char value, or EOF, the behaviour of these functions is undefined.", иначе оно возвращает int, который без потерь кастится в char. тут опять не вижу проблем в применении.
>простите, признаюсь что тупо напал на strlen.
>вы меня не совсем поняли. я говорю о том, как на самом
>деле определена функция, пусть не posix'ом, то хотя бы большим количеством
>описаний в сети. прочитайте его еще раз. написана она в соотв.
>с теми требованиями, которые были к ней до этого, своего ничо
>не добавлял ;) т.о. задачу по реализации считаю выполненной правильно.ОК
>
>если у клиента другая кодировка, то (раз уж мы работаем с содержимым строк как с символами, а не как с байтами туда-обратно) при "не той" кодировке "перестанет" работать и весь clib, так ?нет перстанет работать контекст-зависимая часть функций, т.к. строка (char*) остается нуль-терминированной (до тех пор пока туда не начнут пихать совсем черт знает что), т.е. всякие strcmp, strcpy, работать будут.
> для выбора другой локали есть setlocale(), utf-8 же clib'ом поддерживается только через mbs->wcs, и функции работы с wcs имеют одноименный префикс. где уж это мой недочет ? если программист _действительно_ планирует работу с толстыми буквами, то ему нужно подумать об этом заранее, а не ругать имеющиеся средства. то есть конвертим utf8 в wcs и применяем wcslwr/towlower. с ucs4 конечно на clib'е тяжелее.
Верно, и думать надо т.к. сейчас основной кодировкой становится utf-8, а с strlwr-ориентированными решениями будет беда.
>
>насчет локали. если setlocale() вызвана с верным аргументом, то для любой 8-битной
>кодировки tolower() вернет правильное значение, даже для utf8 (т.к. utf8 в
>плане однобайтных символов идентична 7-bit ascii, и ни одна русская буква
>не попортится). и разумеется *str*lwr не обратит неаскёвую часть.Вот-вот для utf-8 функция например вообще не работает, преобразование будет не выполнено. А это явно не то что хотелось бы.
>
>избитый нами int tolower(int) принимает в нашем контексте всегда не более чем
>char; в мануале сказано, что если "c is not an unsigned
>char value, or EOF, the behaviour of these functions is undefined.",
>иначе оно возвращает int, который без потерь кастится в char. тут
>опять не вижу проблем в применении.в данном конкретном случае да.
>Вот-вот для utf-8 функция например вообще не работает, преобразование будет не выполнено.
>А это явно не то что хотелось бы.мы явно погнули разные линии 8)
иногда ведь это именно то, что хотелось бы, вот тогда мы и называем это желание "strlwr". вспомните хотя бы сканеры языков, сетевых протоколов, и т.д., где перемешаны 2 локали: C и какая-то еще -- они их разделяют. не то что бы в этих случаях не подходила реализация, которая поддерживает еще и утф, нет... просто там этого не надо.
>>Она переводит все семволы строки в нижний регистр.
>
>Стандартной нет. Придётся написать свою, благо это очень легко:
>
>for (int i = 0; i < strlen(string); ++i) {
> string[i] = tolower(string[i]);
>}
>
>Если на С++, то можно transform()'ом пройтись или использовать to_lower() из буста.
>Спасибо!