Parsing .csv with Qt regexp
This code gets all fields in .csv line, works for most cases
QStringList parseLine(const QString &line)
{
// Match against comma, followed by optional \", followed by target, followed by optional \" then comma or end of line
QRegExp rx("(?:^|,)(?:\\s*)\"(.*)\"(?:\\s*)(?:,|$)|(?:^|,)(?:\\s*)([^\"]*)(?:\\s*)(?:,|$)",Qt::CaseSensitive,QRegExp::RegExp2);
rx.setMinimal(true);
QStringList list;
int pos = 0;
while ((pos = rx.indexIn(line, pos)) != -1) {
list << (rx.cap(1).isEmpty() ? rx.cap(2) : rx.cap(1));
pos += rx.matchedLength()-1;
}
return list;
}
еще одно преимущество const в большом проекте
если в проекте повсюду используются модификатор const то имея две функции для обращения к какому-нибудь свойству объекта, одна из которых константна проще отследить где же этот объект или свойство изменяется.
Волшебное заклинание для экспорта DLL
Я нашел волшебное заклинание для упрощения импорта-экспорта шаблонов, функций и классов из DLL. Делюсь.
В общем для библиотеки заголовочном файле напишите такие дефайны:
#ifdef WIN32
# if defined(BUILD_LIBNAME_DLL) && defined(BUILD_LIBNAME_STATIC)
# error You must define only one of the build macross
# endif
# if defined(USE_LIBNAME_DLL) && defined(USE_LIBNAME_STATIC)
# error You must define only one of the build macross
# endif
# ifdef BUILD_LIBNAME_DLL // Create a DLL library
# define LIBNAME_STATIC_MEMBER static
# define LIBNAME_DLL_EXPORT __declspec(dllexport)
# define LIBNAME_DLL_TEMPLATE
# elif defined USE_TGSCORE_DLL // Use a DLL library
# define LIBNAME_STATIC_MEMBER static __declspec(dllimport)
# define LIBNAME_DLL_EXPORT __declspec(dllimport)
# define LIBNAME_DLL_TEMPLATE extern
# endif
# if defined(BUILD_LIBNAME_STATIC) || defined(USE_LIBNAME_STATIC)
# define LIBNAME_STATIC_MEMBER static
# define LIBNAME_DLL_EXPORT
# define LIBNAME_DLL_TEMPLATE
# endif
# if !defined(BUILD_LIBNAME_DLL) && !defined(USE_LIBNAME_DLL) && !defined(BUILD_LIBNAME_STATIC) && !defined(USE_LIBNAME_STATIC)
# error You must define USE_LIBNAME_? or BUILD_LIBNAME_? (see LIBNAMECommon.h)
# endif
#else
# define LIBNAME_STATIC_MEMBER static
# define LIBNAME_DLL_EXPORT
# define LIBNAME_DLL_TEMPLATE
#endif /* WIN32 */
в заголовочнике для экспортируемых классов используйте:
class LIBNAME_DLL_EXPORT ClassName {
};
для экспорта класса.
class ClassName {
LIBNAME_STATIC_MEMBER Name;
};
для экспорта статического члена класса.
LIBNAME_DLL_TEMPLATE template class LIBNAME_DLL_EXPORT std::vector;
для экспорта специализации шаблона.
на этом месте компилер выдаст ошибку при импорте, микрософт говорит что ее можно игнорировать (http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958).
в зависимости от того исполььзуете вы библиотеку или собираете, и dll или статическую, определите один из макросов: BUILD_LIBNAME_DLL, BUILD_LIBNAME_STATIC, USE_LIBNAME_DLL, USE_LIBNAME_STATIC
STL контейнеры и незавершенные типы.
столкнулся с вопросом можно ли делать членами класса STL контейнеры незавершенных типов.
в общем случае создавать такие контейнеры нельзя, такой код не скомпилится:
class foo;
void f() {
std::vector[foo] b;
}
такой как минимум выругается что не может вызвать деструктор:
class bar {
public:
bar(){}
~bar(){}
private:
std::vector[foo] b;
};
а вот если написать
class bar {
public:
bar();
~bar();
private:
std::vector[foo] b;
};
то это уже может и сработать, если std::vector используется только внутри этого класса, главное чтобы там где определяются конструктор и деструктор bar, class foo уже был определен.
но формально это запрещенно, хоть компилеры и не ругаются на такое.
другие контейнеры с незавершенными типами в основном не работают, вектор тут исключение потому что ему внутри нужно хранить только указатель на тип.
crossdomain javascript communication SOLVED!(?)
Once again I tried to solve the problem of communication between two javascripts placed on different domains without server side scripts.
Seems that time I solved it at least partialy.
The solution is simple: remote javascript window should open iframe on local server with hash reference in URL. that local page should be specially crafted to be able to set cookie that contain transmitted data. The dirty example made for servers
local: http://localhost:8000
remote: http://127.0.0.1:8000
directory crazytest,
so you probably have to change it before use.
also it uses jquery:
http://morgoth.at.nsu.ru/crazytest.tar.gz
http://zba.livejournal.com/8617.html
От C++ к Perl и Lisp
если после C++ в перле чувствуешь себя как после грузовика в легковой машине – чуток непривычно, но принцип тот же, то в Lisp ты попадаешь в танк, где вместо руля две ручки для раздельного управления гусеницами.
прямо заново учусь программировать будто.
правило начинающего C++ юзера
если что-то понадобилось сначала посмотри в boost, потом в stl, потом в гугле, потом пиши.
вопросы работодателя 2
Каким образом в С++ можно осуществлять приведение типов данных? В каких ситуациях эти способы предпочтительны?
в плюсах есть несколько механизмов приведения типов
1. при помощи операторов приведения типов и конструкторов.
если у вас есть два класса A и B вы можете определить оператор приведения одного типа к другому
class A {};
class B { public: B (A a) {} };
A a;
B b=a; //неявный вызов оператора приведения типа.
можно вызывать этот оператор явно
b = (B) a; // запись в стиле С
b = B (a); // так наглядней, но работает только в C++
2. dynamic_cast
приведение указателей и ссылок на классы внутри иерархии классов с проверкой корректности времени исполнения. если класс полиморфный то можно не только приводить производный класс к базовому, но и наоборот. в случае если преобразование некорректно возвращает нулевой указатель, есои происходит инициализация ссылки – вызывает исключение
class CBase { };
class CDerived: public CBase { };
CBase b; CBase* pb;
CDerived d; CDerived* pd;
pb = dynamic_cast(&d);
3. static_cast
может то же что и dynamic_cast, но без проверки в runtime – программист сам должен убедится что приведение типа корректно. в случае приведения к классу ниже по иерархии указателя который не ссылается на нужный класс операция будет успешной, но обращение к несуществующим методам будет приводить к ошибкам.
так же static_cast можно применять для приведения встроенных типов и между типами для которых определены соответствующие конструкторы и операторы приведения типов.
4. reinterpret_cast
преобразует любые указатели в другие указатели, а так же производит преобразования между int и указателями.
5. const_cast
позволяет изменять атрибут константности.
когда и что лучше применять – дело традиций проекта в котором вы участвуете.
хорошо аргументировано какой же метод приведения типов использовать в гуловом документе о стиле программирования.
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Casting
они разрешают в своих проектах применять лишь static_cast, const_cast и reinterpret_cast если вы знаете что делаете.
C-подобное приведение типов запрещается из-за того что приходится разбираться что же именно произойдет в результате операции, в случае *_cast все явно.
так же они советуют определять конструкторы принимающие одну переменную как explicit чтобы избежать неявного приведения типов.
применение dynamic_cast разрешается только в unit tests, если оно вам нужно где-то еще – скорее всего у вас ошибка в дизайне.
вопросы работодателя 1
– Чем отличаются const char * ptr и char * const ptr?
тут есть хорошее мнемоническое правило – проводим вертикальную черту по звездочке – то что слева относится к типу, справа – к указателю.
так что первое это указатель на константу, второе – константный указатель.
– В каких случаях целесообразно применять const?
Чтобы показать что переменная не должна изменяться или что функция не меняет параметры переданные по ссылке, или чтобы показать что функция – член класса не меняет состояние этого класса.
использование const вирусно, поэтому вы либо используете его всюду, либо вообще забить на него.
продолжение будет.
Skype и v4l2
при написании v4l2 loopback драйвера я наткнулся на проблему, что хотя опенсорсные программы для просмотра картинки с камеры работают нормально – скайп не хочет показывать ничего, даже мусора, хотя данные он запрашивает и в предоставляемый буфер они пишутся.
оказалось что скайп как-то проверяет данные на соответствие заявляемому формату, так что если его кормить шумом, или просто неверно сформаченой картинкой – он просто покажет зеленый прямоугольник.
и да, скайп понимает только вариации yuv, никакого jpeg или rgb.