1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Пожалуйста, внимательно прочитайте правила раздела.
  3. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Кодерский уголок

Тема в разделе "Мастерская", создана пользователем Dimouse, 10 сен 2006.

  1. Dimouse King of Mice

    Dimouse

    Администратор Переводчик

    Регистрация:
    18 апр 2003
    Сообщения:
    35.153
    В соответствии с назначением раздела, в этой теме предполагается обсуждать конкретные вопросы, которые у вас возникают при создании своих программ (в частности - игр), помогать другим, размещать полезные ссылки на статьи и материалы, которые могут пригодиться другим.

    Что здесь не допускается:
    - беспорядочный флуд на всевозможные темы, в том числе общие обсуждения языков программирования без конкретики (карается по статье "флуд и оффтопик" *),
    - разжигания на темы "что лучше, Си или Си++ и чем они отличаются?", "какой язык программирования лучше X или Y?" и т.п. (карается по статье "флейм и участие в холиварах" *),
    - мерение пиписьками в стиле "я лучше программирую" или "ты не умеешь программировать" (карается по статье "оскорбление участников и их взглядов" *).

    Всё это допускается в специально созданной теме "Беседка для программистов или «Бутерброд с кодом».

    * по усмотрению модератора также возможно применение блокировки в данной теме.

    Оригинальное сообщение
     
    Последнее редактирование модератором: 24 ноя 2014
    CY8R4Y нравится это.
  2.  
  3. hidefromkgb

    hidefromkgb

    Регистрация:
    20 дек 2011
    Сообщения:
    145
    Только если строго в strlen-том элементе. Все, что больше, может быть равно либо не равно в зависимости от транслятора. Undefined behaviour ибо.
    А так да, строки не зря нультерминированными называются.
     
  4. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    hidefromkgb, Не могло ж мне это присниться, вроде ведь делал когда-то research.

    Рыжий Тигра, имел ввиду, например, это (есть и более полезные примеры):
    Код:
    #define _MCHAR(s,i) ((s)[i] << (i) * 8)
    #define MULTICHAR32(s) ((_MCHAR(#s, 0) | _MCHAR(#s, 1)  | _MCHAR(#s, 2)  | _MCHAR(#s, 3)))
    
    int main(int argc, char** argv)
    {
        unsigned mchar = MULTICHAR32(Hi!);
        printf("%s\n", &mchar);
        return 0;
    }


    ---------- Сообщение добавлено в 18:57 ---------- Предыдущее сообщение размещено в 18:18 ----------

    В общем, у меня случился шок, когда я обнаружил, что в майкрософтовском компилере всё это не работает. Потому что был уверен, что когда-то проверял и даже находил где-то документальное подтверждение (но в первую очередь мною использовался тогда Intel-овский).
     
  5. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    nop, агааа! Может, ты тривиально натыкался на выравнивание?
     
  6. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    Рыжий Тигра, не-а. Вроде нормально тестил. Переставлю Интел проверю.
     
  7. hidefromkgb

    hidefromkgb

    Регистрация:
    20 дек 2011
    Сообщения:
    145
    Вот +1 за выравнивание. В конце концов, память сейчас хоть и виртуальная, но не настолько, чтобы отдельное АП заводить под каждую строку.

    Впрочем, попадался мне один такой любопытный хак для отслеживания переполнений: память выделялась на каждый запрос сразу страницами, при этом изначальный адрес выравнивался так, чтобы конец выделенной области приходился ровно на страничную границу, а между такими блоками страниц обязательно шла «пустая», а то и сразу много, обращение к которым немедленно рушило программу в сегфолт. Сколько вся эта лепота кушала памяти, и насколько неторопливо работала, можете представить, но зато для отладки оказалась очень кстати. Разве что в этом случае нули идут до, а не после.

    ---------- Сообщение добавлено в 06:06 ---------- Предыдущее сообщение размещено в 05:44 ----------

    А, да.
    Рыжий Тигра, то, чего Вы хотите добиться, в C++11 называется static_assert. Полезная штука, но увы — раньше 11-го стандарта недоступная, и вынуждающая использовать костыли вроде названных выше.

    ---------- Сообщение добавлено в 06:07 ---------- Предыдущее сообщение размещено в 06:06 ----------

    Offtop
    Тьфу. Забыл про негативное отношение к «Вы». Приношу извинения.
     
  8. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    hidefromkgb, да ептыть, какое выравнивание? я говорю о том, что компилятор не генерировал никаких обращений к памяти, просто брал константные значения символов, причем для запрещенных индексов брал нули.
     
  9. hidefromkgb

    hidefromkgb

    Регистрация:
    20 дек 2011
    Сообщения:
    145
    Ну я ж и говорю, undefined behaviour.
     
  10. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    Э, это неинтересно. Переполнения-то бывают в обе стороны. К тому же игры с отрицательными индексами часто бывают весьма полезны. Или на каждом массиве/указателе задавать направление, с которого ждать переполнений...
    Впрочем, можно ещё способ: весь массив выкладывать на отсутствующие страницы, а в обработчике страничного отлупа каждый раз проверять откуда именно просят. Ну и, ясен перец, будет ещё тормознее. :-(
    Угу. MSVC6 про такое даже не слыхивал. :-(
     
  11. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    Рыжий Тигра, MS вообще му@#ки, стоящие на пути прогресса. До сих пор нормального C99 нету. и оптимизировать нормально не научились, я тут для эквивалентных вариантов простейшего выражения получаю кучу разных вариантов сгенеренного кода, вместо оптимального. Или вот к вышеупомянутому примеру. Undefined behavior или нет, но что это за поведение, если твой "оптимизирующий" компилер умеет взять константный символ из константной строки на этапе компиляции, но вместо взятия какого-нибудь константного для чтения за ее пределами, предпочтет сознательно сгенерировать код, читающий рандомную область памяти? Типа "ага, для этого куска кода нам ничто не мешает либо сделать некрэшащийся код, либо вывести ошибку, но мы сознательно сгенерим код, у которого поведение действительно будет неопределенным" Я не оправдываю себя в использовании такой хрени, но о чем думали создатели компилятора я никогда не мог понять в этом и в множестве других случаев.
     
  12. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    Салют всем!
    Имею ещё один горбатый вопрос. Нужен сишный CSV-парсер для разделки .ass-файлов, крохотный и быстрый как холера (ибо работать ему придётся в ночную смену в горячем цеху вниз головой внутри directshow-фильтра). Поскольку кавычек в CSV-полях, полей в кавычках и тем более многострочных полей не наблюдается, то парсер ими может и не заморачиваться. Но зато есть нестандартность - последнее CSV-поле в субтитре это строка, внутри которой могут быть свои запятые, поэтому идея с копированием каждого поля в отдельный массив char'ов (а тем более в отдельный malloc()'нутый буфер) отпадает однозначно: парсер должен только выдавать указатель на очередное поле и его длину (плюс, ясен перец, номер поля в строке и м.б. номер строки).
    Мне как-то сразу понравился асинхронный парсер от Тадаса Вилкелискиса - маленький и шустрый, может читать входные данные кусками и вызывать для каждого поля callback'ную функцию. Скачал, слегка переделал чтобы callback'ная функция забирала последнее поле целиком со всеми запятыми, встроил в свой dxmci, а как дошло до ходовых испытаний - опаньки: для пустого последнего поле (т.е. случай, когда CSV-строка заканчивается запятой) callback не вызывается вообще. :-(
    В общем, нужен парсер. Подкиньте на бедность :-) кто что может!
     
  13. gudleifr

    gudleifr

    Регистрация:
    16 сен 2006
    Сообщения:
    2.592
    Рыжий Тигра, в таком случае проще всего зафигачить конечный автомат. Т.е. тупо записать что за чем может идти и, что при этом должно запускаться.
    Мои заметки, где можно пропускать все куски на FORTH (веря, что они делают ровно то, что от них требуется).
    Пример собственноручного написания CSV-парсера есть также в ликбезе Кернигана и Пайка "Практика программирования".
     
  14. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    Рыжий Тигра, Ну что.. давай примеры и output format
     
  15. hidefromkgb

    hidefromkgb

    Регистрация:
    20 дек 2011
    Сообщения:
    145
    Рыжий Тигра, есть готовая реализация, даже с поддержкой UTF8. Но есть и недостаток: она, увы, разрушающая. На месте запятой после прочтения следующего значения (и на месте перевода строки после прыжка на новую) в памяти будет лежать нуль.
    Для последнего значения это, впрочем, легко обойти, взяв значение напрямую из необработанного буфера: в конце этой строки обязательно будет нуль, потому что перевод строки уже заменён.
     
    Последнее редактирование: 27 мар 2015
  16. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    (радостно) Пофиг! Давай!

    Это субтитры формата ASS:
    Код:
    [Script Info]
    ; Script generated by Aegisub 3.0.0
    ; http://www.aegisub.org/
    Title: Wing Commander IV: The Price of Freedom -- SC_0010
    ScriptType: v4.00+
    WrapStyle: 0
    ScaledBorderAndShadow: yes
    Collisions: Normal
    PlayResX: 384
    PlayResY: 288
    
    [V4+ Styles]
    Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
    Style: wc40,Verdana,16,&H00FFFFFF,&H000000FF,&H30000000,&H80000000,0,0,0,0,100,100,0,0,1,3,1,2,10,10,16,1
    Style: wc41,Verdana,16,&H00FFFFFF,&H000000FF,&H30000000,&H80000000,0,0,0,0,100,100,0,0,1,3,1,2,10,10,40,1
    
    [Events]
    Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
    Dialogue: 0,0:00:40.60,0:00:45.60,wc40,,0,0,0,,
    Dialogue: 0,0:00:53.76,0:00:56.30,wc40,,0,0,0,,Home stretch, boys. Status report.
    Dialogue: 0,0:00:56.40,0:00:58.00,wc40,,0,0,0,,Green 2 to Green Leader: All clear.
    Обрати внимание - в секции "[Events]" первый Dialogue заканчивается на запятую. Вот тут и грабля. Можно, конечно, заранее проинициализировать переменные, в которые callback'ная функция разложит указатель на последнее поле и его длину, но так будет неясно - а есть ли вообще эта последняя запятая (если нет - наморду нарушение формата), да и просто хочется чтобы было "в общем виде".
    А с выходным форматом - и того проще. Надо распихать стили и диалоги по соответствующим структурам:
    Код:
    typedef struct { // ASS [V4+ Styles] - style values
      const char *Name;     // "wc40", etc.
      const char *Fontname; // "Verdana"
      uint32_t numbers[ 21 ];
    // 5: Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour,
    // 9: Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle,
    // 7: Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
    } vsub_ass_style_t;
    
    typedef struct { // ASS [Events] - Dialogue values:
      int32_t start_time, stop_time; // в миллисекундах
      const char *style_str; // поле Style
      int layer, marginl, marginr, marginv;
      const char *name, *effect; // поля Name и Effect
      const char *text;       // собственно строка субтитра
      int textlen; // длина строки субтитра
    } vsub_t_str_t;
    - дальше прога проверит на совместимость нескольких файлов, слепит из них индексный, выведет его...
    Есть ещё и третий формат - внутриdirectshow'ный субтитровый поток, но с ним я пока застрял и годного образца на руках не имею. :-(

    ---------- Сообщение добавлено в 00:16 ---------- Предыдущее сообщение размещено в 00:10 ----------

    "Дядь, ну я же сварщик не настоящий, я это всё на стройке нашёл..." (L) :-)
    Не давали нам конечных автоматов. Программистам давали, а радиоконструкторам-технологам - нет. :-(
    Сенькс, пороюсь.
     
  17. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    Кстати. Я тут на досуге гонял очень простенькую матрицу тестов на 4 компиляторах. Вышло как-то так:
    Clang >= GCC >> IntelCC > MSVC
    Причем только Clang/LLVM(3.4) отработал идеально. GCC - неплохо. Intel(13) и Microsoft (VS2013)- тупой и еще тупее. У интеловского еще и какая-то обфускация есть.

    ---------- Сообщение добавлено в 02:25 ---------- Предыдущее сообщение размещено в 01:25 ----------

    Рыжий Тигра, код сырой, но работает. Парсю только строки с диалогом, остальное - по аналогии.
    Код:
    int split_line(char *s, char *parms[], intptr_t n)
    {
        intptr_t i = 0;
        while (1) {
            while (*s && *s <= ' ') ++s;
            parms[i] = s;
            if (++i >= n) return 0;
            while (*s && *s != ',') ++s;
            if (!*s) return -1;
            *s++ = 0;
        }
    }
    
    #define ISNUM(c) ((unsigned)(c - '0') < 10)
    
    int32_t parse_time(char *s)
    {
        int x = 0, y, c;
        while (1) {        
            switch (c = *s++) {
            case ':':
                x *= 60;
                break;
    
            case '.':
                x *= 1000;
                for (y = 100; ISNUM(*s); y /= 10, ++s)
                    x += y * (*s - '0');
                return x;
    
            case 0:
                return x * 1000;
    
            default:
                if (ISNUM(c)) {
                    x += atoi(s - 1);
                    while (ISNUM(*s)) ++s;
                }
            }            
        }
    }
    
    void miniparser(void)
    {
        const char * src = "[Events]\n"
            "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"
            "Dialogue: 0,0:00:40.60,0:00:45.60,wc40,,0,0,0,,\n"
            "Dialogue: 0,0:00:53.76,0:00:56.30,wc40,,0,0,0,,Home stretch, boys. Status report.\n"
            "Dialogue: 0,0:00:56.40,0:00:58.00,wc40,,0,0,0,,Green 2 to Green Leader: All clear.\n";
    
        
        vsub_t_str_t substr[5]; // TODO: allocate as needed
        int i_substr = 0;
    
        char * ss = strdup(src);
        char *s = strtok(ss, "\r\n");
        while (s) {
            if (0 == strncmp(s, "Dialogue: ", 10)) {
                vsub_t_str_t &o = substr[i_substr++];
                char *p[10];
                split_line(s + 10, p, 10);
                o.layer = atoi(p[0]);
                o.start_time = parse_time(p[1]);
                o.stop_time = parse_time(p[2]);
                o.style_str = p[3];
                o.marginl = atoi(p[4]);
                o.marginr = atoi(p[5]);
                o.marginr = atoi(p[6]);
                o.name = p[7];
                o.effect = p[8];
                o.text = p[9];
            }
            s = strtok(NULL, "\r\n");
        }
    }
     
    Последнее редактирование: 28 мар 2015
  18. hidefromkgb

    hidefromkgb

    Регистрация:
    20 дек 2011
    Сообщения:
    145
    Вот.
    Имел наглость вместе с самим кодом набросать (без понимания происходящего в недрах файла) примитивный каркас результриующего разборщика.
    Код:
    #include <stdint.h>
    #include <stdio.h>
    /// Needed for LoadFile()
    #include <fcntl.h>
    
    
    
    /// Default header separator
    #define DEF_HSEP ':'
    /// Default token separator
    #define DEF_TSEP ','
    /// Default comment
    #define DEF_CMNT ';'
    
    
    
    /// Empty hash
    #define ERR_HASH 0
    /// String-oriented linear hash multiplier
    #define SLH_MULT 0xFBC5
    /// String-oriented linear hash shift
    #define SLH_PLUS 0x11
    
    uint32_t HashLine(char *line, long size) {
        uint32_t hash = ERR_HASH;
    
        if (!size)
            size--;
        while (*line && size--)
            hash = SLH_PLUS + SLH_MULT * hash + *line++;
        return hash;
    }
    
    
    
    /// [TODO] make this mess UTF8-compliant
    char *ToLower(char *uppr, long size) {
        long iter;
    
        if (uppr) {
            if (!size)
                size = strlen(uppr);
            for (iter = 0; iter < size; iter++)
                uppr[iter] = tolower(uppr[iter]);
        }
        return uppr;
    }
    
    
    
    char *SkipCharUTF8(char *line) {
        static char skip[] = {2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6};
        return line + (((*line & 0xC0) == 0xC0)? skip[((*line) >> 2) & 0x0F] : 1);
    }
    
    
    
    long WhitespaceUTF8(char *line) {
        switch (line[0]) {
            case '\x09':
            case '\x20':
                return ~0;
            case '\xC2':
                if (line[1] == '\xA0') return ~0; break;
            case '\xE1':
                if (line[1] == '\x9A' && line[2] == '\x80') return ~0; break;
            case '\xE3':
                if (line[1] == '\x80' && line[2] == '\x80') return ~0; break;
            case '\xEF':
                if (line[1] == '\xBB' && line[2] == '\xBF') return ~0; break;
            case '\xE2':
                switch (line[1]) {
                    case '\x81': if (line[2] == '\x9F') return ~0; break;
                    case '\x80':
                        switch (line[2]) {
                            case '\x80':
                            case '\x81':
                            case '\x82':
                            case '\x83':
                            case '\x84':
                            case '\x85':
                            case '\x86':
                            case '\x87':
                            case '\x88':
                            case '\x89':
                            case '\x8A':
                            case '\x8B':
                            case '\xAF': return ~0;
                        }
                }
        }
        return 0;
    }
    
    
    
    char *SplitLine(char **tail, char tsep, long keep) {
        char *retn, *temp, *iter = *tail;
    
        if (*tail) {
            while (WhitespaceUTF8(iter))
                iter = SkipCharUTF8(iter);
            if (*iter) {
                if (!(*tail = strchr(iter, tsep)))
                    *tail = iter + strlen(iter);
                temp = retn = iter;
                while (iter < *tail) {
                    if (!WhitespaceUTF8(iter))
                        temp = iter;
                    iter = SkipCharUTF8(iter);
                }
                *tail = (**tail)? *tail + 1 : 0;
                if (*temp) {
                    if (*temp != tsep)
                        temp++;
                    if (!keep)
                        *temp = 0;
                }
                return retn;
            }
            *tail = 0;
        }
        return *tail;
    }
    
    
    
    uint32_t DetermineType(char **tail) {
        char *lent, *temp = SplitLine(tail, DEF_HSEP, 1);
    
        if (temp && (*temp != DEF_CMNT)) {
            lent = (*tail)? *tail : temp + strlen(temp) + 1;
            return HashLine(ToLower(temp, lent - temp - 1), lent - temp - 1);
        }
        return ERR_HASH;
    }
    
    
    
    char *GetNextLine(char **file) {
        char *retn;
        long  iter;
    
        if ((retn = SplitLine(file, '\n', 0)))
            if ((iter = strlen(retn)) > 0)
                if (retn[iter - 1] == '\r')
                    retn[iter - 1] = '\0';
        return retn;
    }
    
    
    
    char *LoadFile(char *name) {
        char *retn = 0;
        long file, flen;
    
        if ((file = open(name, O_RDONLY)) > 0) {
            flen = lseek(file, 0, SEEK_END);
            lseek(file, 0, SEEK_SET);
            retn = malloc(flen + 1);
            read(file, retn, flen);
            retn[flen] = '\0';
            close(file);
        }
        return retn;
    }
    
    
    
    /// '[script info]'
    #define SCR_INFO 0xB73A8BC6
    /// '[v4+ styles]'
    #define SCR_STYL 0x45D4B845
    /// '[events]'
    #define SCR_EVTS 0x13E207AD
    
    /// 'title'
    #define TKN_TITL 0xC8D60FEB
    /// 'scripttype'
    #define TKN_SCRT 0xC8A74EA9
    /// 'wrapstyle'
    #define TKN_WSTL 0x34597C5C
    /// 'scaledborderandshadow'
    #define TKN_SBNS 0x9B4DE8F4
    /// 'collisions'
    #define TKN_COLL 0x1B916639
    /// 'playresx'
    #define TKN_RESX 0x34764A30
    /// 'playresy'
    #define TKN_RESY 0x34764A31
    /// 'format'
    #define TKN_FRMT 0x8BCCA3A7
    /// 'style'
    #define TKN_STYL 0xE3941996
    /// 'dialogue'
    #define TKN_DIAL 0x7777AF2E
    
    
    
    #define TRY_TEMP(conf) (GET_TEMP(conf) && *temp)
    #define GET_TEMP(conf) (temp = SplitLine(conf, DEF_TSEP, 0))
    int main(int argc, char *argv[]) {
        char *file, *fptr, *conf, *temp;
        uint32_t mode = ERR_HASH;
    
        if ((argc > 1) && (file = LoadFile(argv[1]))) {
            fptr = file;
            if ((strlen(fptr) > 3)
            &&  (fptr[0] == 0xEF) && (fptr[1] == 0xBB) && (fptr[2] == 0xBF))
                fptr += 3;
            while ((conf = SplitLine(&fptr, '\n', 0)))
                switch (DetermineType(&conf)) {
                    case SCR_INFO:
                        mode = SCR_INFO;
                        break;
    
                    case SCR_STYL:
                        mode = SCR_STYL;
                        break;
    
                    case SCR_EVTS:
                        mode = SCR_EVTS;
                        break;
    
                    case TKN_FRMT:
                        if (mode == SCR_STYL) {
                            printf("-=<[ STYLE FORMAT ]>=-\n");
                            if (TRY_TEMP(&conf))
                                printf("Name = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Fontname = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Fontsize = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("PrimaryColour = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("SecondaryColour = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("OutlineColour = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("BackColour = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Bold = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Italic = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Underline = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("StrikeOut = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("ScaleX = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("ScaleY = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Spacing = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Angle = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("BorderStyle = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Outline = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Shadow = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Alignment = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("MarginL = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("MarginR = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("MarginV = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Encoding = '%s'\n", temp);
                            printf("\n");
                        }
                        else if (mode == SCR_EVTS) {
                            printf("-=<[ EVENT FORMAT ]>=-\n");
                            if (TRY_TEMP(&conf))
                                printf("Layer = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Start = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("End = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Style = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Name = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("MarginL = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("MarginR = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("MarginV = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Effect = '%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("Text = '%s'\n", temp);
                            printf("\n");
                        }
                        break;
    
                    case TKN_DIAL:
                        if (mode == SCR_EVTS) {
                            printf("-=<[ EVENT DIALOGUE ]>=-\n");
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (TRY_TEMP(&conf))
                                printf("'%s'\n", temp);
    
                            if (conf)
                                printf("Phrase = '%s'\n\n", conf);
                        }
                        break;
                }
            free(file);
        }
        else
            printf("Cannot read file!\n");
        return 0;
    }
    
     
    Последнее редактирование: 28 мар 2015
  19. Рыжий Тигра Сам себе «пират»

    Рыжий Тигра

    Регистрация:
    3 май 2012
    Сообщения:
    1.823
    nop, hidefromkgb, сенькс! Изучаю. До сих пор знал только один подход к разделке CSV - "асинхронный" на callback'ах, как у Вилкелискиса. Теперь в копилке будет ещё.
     
  20. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    Рыжий Тигра, Ну, мой код проверен, считывает кусок текста из твоего поста в структуру оттуда же. Может лишь понадобиться шлифовка типа проверки, не захватывает ли он символ конца строки, добавление растущего буфера (проще всего написать на STL), освобождение памяти. Я даже написал и отладил довольно хитрый парсер таймстампа :)

    Код:
    #include <vector>
    ...
    
    std::vector<vsub_t_str_t> sub;
    ....
    sub.resize(sub.size() + 1);
    vsub_t_str_t &o = sub.back();
    ....
    


    ---------- Сообщение добавлено в 17:54 ---------- Предыдущее сообщение размещено в 17:48 ----------

    CSV, а особенно его диалект в отдельно взятом формате, прост как валенок. Не вижу смысла сильно извращаться, когда можно с нуля разделать за час.
     
    Последнее редактирование: 30 мар 2015
  21. Steel Rat Stainless

    Steel Rat

    Регистрация:
    28 дек 2006
    Сообщения:
    3.260
    Не понял, какие тесты, о чём речь?
     
  22. nop

    nop

    Регистрация:
    5 дек 2014
    Сообщения:
    2.297
    Steel Rat, Это был простой performance test, элементарно простой, в множестве вариантов. Настолько простой, что я бы никогда не подумал, что компиляторы настолько жестоко на нем обломаются. Тут писать не буду, может, если найду время, засуну на хабр.
     
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление