Методы работы с текстом.
CString sWord = "word";
и обращаюсь к буквам как
dc.TextOut(x, y, sWord[0]);
а в VC7 так не получается, как можно работать с отдельными буквами слова.
т.е. я не хочу разбивать слово на отдельные компоненты типа ... = {"w", "o", "r", "d"};
вот например такой код (точнее просто смысл кода):
CString letter = "w";
for(int i = 0; i<4; i++)
{
if(sWord == letter)
MessagwBox("The letter is enable", "Congratulations!!!", MB_OK);
break;
}
расскажите подробнее пожалуйста, у меня часто такие вопросы возникают, тольком поговорить нескем.
Вот определение из MSDN
void Format( LPCTSTR lpszFormat, ... );
void Format( UINT nFormatID, ... );
(...) - это и есть массив void* БЕЗ УКАЗАНИЯ РАЗМЕРА этого массива!
Алгоритмы парсинга уже давно отлажены и никаких проблем не представляют.
Представляют, нарпример, для быстродействия.
Парсинг то формата выполняется в рантайме.
Ну и плюс, потенциальные ошибки в самой строке формата. Но я уже повторяюсь.
Преобразования в текстовый формат везде выролняются runtime. ( не будешь же ты утверждать что "i=" << i производится в процессе компиляции)
Я с этим и не спорил...
При введении новых типов нужно определять оператор "<<". Возможности форматирования СString также могут быть расширены.
Я не в курсе, как расширяются возможности форматирования CString без изменения самого класса CString. Поделись знанием. :)
Действительно ИМХО существенное отличие - это необходимость задавать тип форматирования в отрыве от формата данных. Однако вызванные этим ошибки легко локализуются, т.к. тут же видишь их последствия.
Не всегда они легко локализуются, например, при выводе больших объемов текста таких, как HTML-страницы, текстовые файлы БД и т.п. Но не будем на этом заостряться. В любом случае их нужно ЛОКАЛИЗОВЫВАТЬ, а для этого дождаться процесса отладки. Я не против отладки, но я все же сторонник выявления ошибок до начала отладки: в процессе компиляции и юнит-тестирования.
... зачем использовать гибрид С & С++
если вы пишете на С++? я всегда думал что это два разных языка. а преобразования подобные printf - по моему не С++ way ;)
1. Здесь цитата Страутструпа от Mamontoboy , "С является подмножеством С++". И при желании можно эту мысль основателя итерпретировать и так: "написанное на С годится и для С++"
2. CString является классом - т.е. соотв. фундаментальной парадигме С++. Format - один из многих членов этого класса. А то, что формат параметров функции Format совпадает с форматом си-шной fprint ИМХО не является основанием для обвинения в осквернении святыни С++.
Надеюсь, в отношении оператора if подобные подозрения в "не С++ way" не возникают.
Вопрос правоверности скользкий и взрывоопасный.
Главная проблема - выбор объективного критерия
и кто будет оценивать эту правоверность.
1. Здесь "С является подмножеством С++". И при желании можно эту мысль основателя итерпретировать и так: "написанное на С годится и для С++"
не знаю чем руководствовался Страуструп. Я бы посмотрел последнее издание его фундаментального труда. Оно, говорят, в прошлом году вышло. Далеко не все написанное на С годиться для С++, думаю если вы хорошо подумаете над отличиями языков, вы со мной согласитесь.
вопрос правоверности скользкий и взрывоопасный.
Главная проблема - выбор объективного критерия
и кто будет оценивать эту правоверность.
не я - точно. поэтому не буду углубляться в дискуссию.
Представляют, нарпример, для быстродействия.
Парсинг то формата выполняется в рантайме.
Ну и плюс, потенциальные ошибки в самой строке формата. Но я уже повторяюсь.
Стандартная операция всегда выполняется дольше, чем специализированная. Поэтому когда явно указываешь тип преобразования, время на обработку уходит меньше. Пример:
CString str;
for(int i = 0; i < 1000; i++)
for(int y = 0; y < 1000; y++)
str.Format("I am %d years old", 100 );
эта операция на моем компе выполняется около 2700 мс (+- 100 мс)
std::ostringstream os;
std::string str1;
for(int i = 0; i < 1000; i++)
for(int y = 0; y < 1000; y++)
os << "I am " << 100 << " years old";
порядка 2900 мс, а если еще в цикл добавить
str1 = os.str(); , то время вырастит еще
а насчет ошибок при реализации не проще ли написать свой класс для работы со строками?
Поэтому когда явно указываешь тип преобразования, время на обработку уходит меньше.
Чего? Что ты имел в виду? Какой и где тип ты указываешь явно?
Пример:
CString str;
for(int i = 0; i < 1000; i++)
for(int y = 0; y < 1000; y++)
str.Format("I am %d years old", 100 );
эта операция на моем компе выполняется около 2700 мс (+- 100 мс)
std::ostringstream os;
std::string str1;
for(int i = 0; i < 1000; i++)
for(int y = 0; y < 1000; y++)
os << "I am " << 100 << " years old";
порядка 2900 мс, а если еще в цикл добавить
str1 = os.str(); , то время вырастит еще
М-да... Неверной дорогой идете товаристч.
Так не сравнивают.
а насчет ошибок при реализации не проще ли написать свой класс для работы со строками?
Не проще.
Чего? Что ты имел в виду? Какой и где тип ты указываешь явно?
Я явно указываю (%d), что преобразую целое число в строку, а <<100 - не ясно, что это за тип данных
Я явно указываю (%d), что преобразую целое число в строку, а <<100 - не ясно, что это за тип данных
мда...
и если я напишу
я буду обруган компилятором???
мда...
и если я напишу
я буду обруган компилятором???
А ты напиши так и посмотри результат
А ты напиши так и посмотри результат
а мне результат не важен. важно то, что он ЕСТЬ. если бы компилятор послал меня нафиг и сказал бы, что указанный спецификатор %d не соответствует типу передаваемого параметра я бы согласился, что тут явное указание типов.
а мне результат не важен. важно то, что он ЕСТЬ. если бы компилятор послал меня нафиг и сказал бы, что указанный спецификатор %d не соответствует типу передаваемого параметра я бы согласился, что тут явное указание типов.
Компилятор действует в соответствии с поставленной ему инструкцией, а если ты будешь писать код, так что "бы компилятор НЕ послал тебя нафиг", то получится замечательный программный продукт :). Написать можно, что угодно - программа пишется не для компилятора, а как раз для результата
Компилятор действует в соответствии с поставленной ему инструкцией, а если ты будешь писать код, так что "бы компилятор НЕ послал тебя нафиг", то получится замечательный программный продукт :). Написать можно, что угодно - программа пишется не для компилятора, а как раз для результата
так то оно так, только по мне, так лучше, чтобы ошибки ловились на самых ранних этапах. а не искались потом бессонными ночами с помощью отладчиков.
так то оно так, только по мне, так лучше, чтобы ошибки ловились на самых ранних этапах. а не искались потом бессонными ночами с помощью отладчиков.
А что если компилятор не правильно определит тип данных для преобразования? Все таки программист лучше знает, что и как надо преобразовать
(...) - это и есть массив void* БЕЗ УКАЗАНИЯ РАЗМЕРА этого массива!
Эта синксическая конструкция определяет функцию с переменным кол-вом пераметров и НИЧЕГО БОЛЕЕ!
Нет здесь void*, нет здесь никакого массива!
Параметры напрямую запихиваются в стек из переменных. То же самое делается и в случае с фиксированным кол-вом параметров, но с учетом типов.
Никакого void* здесь нет!
Нетерпимость к этому типу к данному случаю не относится
Все таки программист лучше знает, что и как надо преобразовать
вы уверены? я вот не очень...
Я явно указываю (%d), что преобразую целое число в строку, а <<100 - не ясно, что это за тип данных
Ну тебе то может и не ясно, да это и не важно, главное, что компилятору понятно. Тип явно задается передаваемым параметром, а не в строке для парсинга.
А что если компилятор не правильно определит тип данных для преобразования?
Пример, пожалуйста. А пока будем утверждать, что компилятор не может "не правильно определить тип данных", иначе он может и неправильно определить имя функции или неправильно понять смысл оператора и т.п.
Все таки программист лучше знает, что и как надо преобразовать
Ну так не используй типы вообще... Вернее используй один единственный интергральный тип, например int, этого вполне достаточно для написания любой программы.
Эта синксическая конструкция определяет функцию с переменным кол-вом пераметров и НИЧЕГО БОЛЕЕ!
Назови мне тип этих параметров.
Нет здесь void*, нет здесь никакого массива!
Параметры напрямую запихиваются в стек из переменных.
Переменный какого типа?
Да, информация помещается в стек, но это реализация.
Не нравится слово "массив", давай применим слово "набор", "коллекция", "стек". Это не имеет значения.
Меня интересует: я могу узнать на приемной стороне (внутри функции) напрямую размер коллекции (глубину стека)? Я могу напрямую восстановить типы переданных значений?
Ответ на оба вопроса - НЕТ.
Никакого void* здесь нет!
Нетерпимость к этому типу к данному случаю не относится
Ещё раз повторю вопрос: какого типа данные лежат в передаваемом наборе, а какие типы помещались в набор?
Потеря типа (обезличивание данных) и входит в проблему, которая для краткости именуется, как "void*"
Надеюсь, в отношении оператора if подобные подозрения в "не С++ way" не возникают.
Возникают.
Т.к. С++ является ООП языком, множество конструкций с if заменяются использованием ОО механизмов (см. паттерны "Стратегия", "Фабрика объектов" и пр.)
Ну так не используй типы вообще... Вернее используй один единственный интергральный тип, например int, этого вполне достаточно для написания любой программы.
Возникают.
Т.к. С++ является ООП языком, множество конструкций с if заменяются использованием ОО механизмов (см. паттерны "Стратегия", "Фабрика объектов" и пр.)
Ура!!!!
Пишем линейные программы, параметры не проверяем(все и так всегда правильные ), и используем только int. И все быстро красиво и правильно сваяем!
А почему int'у такая привилегия? Тоже ведь жалкое наследие C?
Пример, пожалуйста. А пока будем утверждать, что компилятор не может "не правильно определить тип данных", иначе он может и неправильно определить имя функции или неправильно понять смысл оператора и т.п.
Вернее компилятор не знает какой тип данных нужен программисту - он действует в зависимости от данных.
Пример:
Из 100.1 мне надо 100, я напишу %d и все
И вообще смысл спорить, что лучше. Для быстрого и простого написания программы, как просил создатель этой темы, я ему предложил CString из MFC
Ура!!!!
Пишем линейные программы, параметры не проверяем(все и так всегда правильные ), и используем только int. И все быстро красиво и правильно сваяем!
А почему int'у такая привилегия? Тоже ведь жалкое наследие C?
Для написания самых правильных программ надо использовать примитивы языка и не заботится о преобразованиях
Потеря типа (обезличивание данных) и входит в проблему, которая для краткости именуется, как "void*"
Проблему неопределенности типов никто не отрицал
А высказывание
(...) - это и есть массив void* БЕЗ УКАЗАНИЯ РАЗМЕРА этого массива!
просто неправильно.
Ура!!!!
Пишем линейные программы, параметры не проверяем(все и так всегда правильные ),
Перед тем, как юродствовать, ты ознакомился с паттернами перечисленными в скобках?
и используем только int. И все быстро красиво и правильно сваяем!
Что ты там говорил про фразы, вырванные из контекста и т.п.?
Кстати и про неотвеченные вопросы тоже много было сказано...
впрочем как и заданных мной вопросов...
А почему int'у такая привилегия? Тоже ведь жалкое наследие C?
Потому, что не жалкое.
Вернее компилятор не знает какой тип данных нужен программисту - он действует в зависимости от данных.
Пример:
Из 100.1 мне надо 100, я напишу %d и все
А я напишу (int) и все.
Кстати, а ты пробовал написать %d для 100.1 ? :D
Попробуй, будешь удивлен!
Перед тем, как юродствовать, ты ознакомился с паттернами перечисленными в скобках?
C чего это ты решил, что я с обобщенным программированием не знаком?
А твое высказывание по поводу if и int подтвердили взрывоопасность вопроса о чистоте С++. Вот и судья вызвался и критерии правоверности(паттерны) обозначены.
Что ты там говорил про фразы, вырванные из контекста и т.п.?
Еще раз привожу ПОЛНОСТЬЮ цитаты из твоих постов
Может что между строк проглядел?
Возникают.
Т.к. С++ является ООП языком, множество конструкций с if заменяются использованием ОО механизмов (см. паттерны "Стратегия", "Фабрика объектов" и пр.)
Блестящие "рекомендации" возврата лет эдак на 35 назад.
впрочем как и заданных мной вопросов...
Если ты о типах переменных в Format(), то в дос. все написано. При вызове параметры не проверяются, а на вызываемой стороне рассатриваются в соотватствии с типами из строки форматирования. Связанная с этим проблема обсуждалась уже не один раз.
Еще что-нибудь забыл?
Теперь у меня вопрос:
Как с пом потоков задать вывод чисел напр. с 4 знаками после зпт?
Блестящие "рекомендации" возврата лет эдак на 35 назад.
Какие? Про использования int в качестве одного типа?
Это называется САРКАЗМ.
Про замену множества if-ов использованием механизмов ООП ?
Я тут другого мнения: это шаг вперед, а не назад.
Теперь у меня вопрос:
Как с пом потоков задать вывод чисел напр. с 4 знаками после зпт?
Для форматирования вывода существуют соотв. методы стандартных потоков, а так же манипуляторы.
Конкретно для твоего вопроса нужен манипулятор setprecision или тождественный метод ios_base::precision.
Теперь у меня вопрос:
Как с пом потоков задать вывод чисел напр. с 4 знаками после зпт?
А можно мне вопос: "Как припомощи CString считывать данные с магнитной ленты, то-есть стриммера? или работать с каналом по-которому пердаются сигналы? В случае с потоками, все ясно, но вот c CString что-то не очень."
Для форматирования вывода существуют соотв. методы стандартных потоков, а так же манипуляторы.
Конкретно для твоего вопроса нужен манипулятор setprecision или тождественный метод ios_base::precision.
int count = -9234;
double d1 = 251.7366;
double d2 = 1234567.7654321;
s.Format("%6d %+8.4f %15.7f", count, d1, d2);
А как выглядит такая конструкция?
А можно мне вопос: "Как припомощи CString считывать данные с магнитной ленты, то-есть стриммера? или работать с каналом по-которому пердаются сигналы? В случае с потоками, все ясно, но вот c CString что-то не очень."
Вопрос не понятен. Cуществуют ли средства (аналог потоков) чтобы данные с МЛ запихнуть в CString? Уточни, пожалуйста.
int count = -9234;
double d1 = 251.7366;
double d2 = 1234567.7654321;
s.Format("%6d %+8.4f %15.7f", count, d1, d2);
А как выглядит такая конструкция?
Ну так попробуй сделать сам такую конструкцию.
Это позволяют сделать стандартные манипуляторы.
Если у тебя не получится, я помогу.
Ну так попробуй сделать сам такую конструкцию.
Это позволяют сделать стандартные манипуляторы.
Если у тебя не получится, я помогу.
Уже не получилось, помогай.
Пожалуйста, несколько строк кода с тем же конечным эффектом
Уже не получилось, помогай.
Пожалуйста, несколько строк кода с тем же конечным эффектом
<< showpos << setw(8) << setprecision(4) << d1 << " "
<< noshowpos << setw(15) << setprecision(7) << d2;
Конечно, код выглядит более внушительным, но зато более наглядным, чем все эти точечки, плюсики.
Вопрос не понятен. Cуществуют ли средства (аналог потоков) чтобы данные с МЛ запихнуть в CString? Уточни, пожалуйста.
Дело не только в магнитной ленте. Имеется ввиду что у тебя есть канал, по которому постоянно приходит сигнал. А тебе нужно этот сигнал обрабатывать. Я, к примеру, не знаю как при помощи CString такое сделать. Потоки сразу рассчитаны на работу с подобными источниками данных, поэтому, имхо, они универсальней, к тому же не требуют ничего кроме стандарта.
Дело не только в магнитной ленте. Имеется ввиду что у тебя есть канал, по которому постоянно приходит сигнал. А тебе нужно этот сигнал обрабатывать. Я, к примеру, не знаю как при помощи CString такое сделать. Потоки сразу рассчитаны на работу с подобными источниками данных, поэтому, имхо, они универсальней, к тому же не требуют ничего кроме стандарта.
Если бы ты сказал, что знаешь как это сделать при помощи std::string, то вопрос был бы понятен. Потоки и СString относятся к разным категориям и ИМХО между собой не сопоставимы.
А уважаемый Green укажет товаристчам верную дорогу и покажет, что std:: string работает быстрее чем CSting.
<< showpos << setw(8) << setprecision(4) << d1 << " "
<< noshowpos << setw(15) << setprecision(7) << d2;
Конечно, код выглядит более внушительным, но зато более наглядным, чем все эти точечки, плюсики.
А что если мне надо просто получить строку этих чисел без вывода их в поток?
А что если мне надо просто получить строку этих чисел без вывода их в поток?
Ты имел в виду: "без вывода их в стандартный поток вывода (stdout)" ?
Использовать поток, и применить str()
См. вторую страницу обсуждения.
Ты имел в виду: "без вывода их в стандартный поток вывода (stdout)" ?
Использовать поток, и применить str()
См. вторую страницу обсуждения.
Я это видел, но это не всегда совсем то, что мне надо. Это нельзя сделать без потока? И время выполнения достаточно большое!!! Еще раз повторюсь, что для каждой задачи нужна своя реализация и вопрос, что лучше надо оставить до конкретной задачи
Если бы ты сказал, что знаешь как это сделать при помощи std::string, то вопрос был бы понятен. Потоки и СString относятся к разным категориям и ИМХО между собой не сопоставимы.
Конечно несопоставимы: std значительно лучше CString. :)
Я себе представляю как это сделать и с помощью std::string и CString. Только метод сильно гемморойный.
Потоки и CString не относятся к разным категориям. А если так к чему сравнивать std:string и CString? std::string разве не использует потоки?
Я это видел, но это не всегда совсем то, что мне надо. Это нельзя сделать без потока?
А можно printf без строки форматирования? :)
И время выполнения достаточно большое!!!
Относительно чего?
Еще раз повторюсь, что для каждой задачи нужна своя реализация и вопрос, что лучше надо оставить до конкретной задачи
Есть некоторые обобщенные принципы, которых следуется придерживаться всегда, не смотря на "легкость" противоречивых решений. Так к примеру, я предпочитаю использовать гетеры и сетеры, а не объявлять поля данных в паблик секции. Так к примеру, я предпочитаю писать тесты до кода. Так к примеру, я использую интерфейсы (абстрактные классы), а не void*. Так я предпочитаю использовать класс-обходчик для коллекций, а не писать обход каждый раз для своей цели. Так к примеру, я использую потоки, а не printf. И т.д.
А можно printf без строки форматирования? :)
Конечно нет, но если я сначала хочу сформировать общую строку без вывода её в поток? Format(...)
Есть некоторые обобщенные принципы, которых следуется придерживаться всегда, не смотря на "легкость" противоречивых решений. Так к примеру, я предпочитаю использовать гетеры и сетеры, а не объявлять поля данных в паблик секции. Так к примеру, я предпочитаю писать тесты до кода. Так к примеру, я использую интерфейсы (абстрактные классы), а не void*. Так я предпочитаю использовать класс-обходчик для коллекций, а не писать обход каждый раз для своей цели. Так к примеру, я использую потоки, а не printf. И т.д.
Интересно было посмотреть как при программировании под Win для использования оконных процедур использовать потоки?
ПыСы. Кстати, а void* кстати прикольная штучка если уметь ею пользоваться...