Russian Qt Forum

Программирование => С/C++ => Тема начата: _Vitaliy_ от Декабрь 05, 2015, 14:50



Название: strtok и много ,,,,,,
Отправлено: _Vitaliy_ от Декабрь 05, 2015, 14:50
Почти литературный пример но все же.

Имеем текстовый файл (пример строки):
0.0117,,,,,,,42,,,0,,,,        (15 числомест)

Нужно заполнить строку в таблице данными из предоставленной строки по условию:
если есть число то заносим число, если "пустышка" то заносим "-"
strtok в моем коде игнорирует "пустышки" поэтому данные заполняются неверно....
привожу псевдокод (f - строка из файла):
Код:
char *ptr;
char *Delitemes= ",\n";
ptr = strtok(f, Delitemes);
while (ptr != NULL) {
    ptr= strtok(NULL, Delitemes);
    // заносим данные
}

в итоге есть только 3 значения...  Как это победить?


Название: Re: strtok и много ,,,,,,
Отправлено: Igors от Декабрь 05, 2015, 15:44
Такие задачки не так уж просты если добросовестно проверять все ошибки. Напр какой рез-т ожидается для
Цитировать
0.17, 6 , 4 3 , , -
?
Если "говнокодить комфортно", то проще всего QString::split (сначала разбить на строки)


Название: Re: strtok и много ,,,,,,
Отправлено: m_ax от Декабрь 05, 2015, 16:03
Цитировать
в итоге есть только 3 значения...  Как это победить?

Посмотрите на boost::tokenizer или boost::spirit


Название: Re: strtok и много ,,,,,,
Отправлено: Fat-Zer от Декабрь 05, 2015, 19:57
всё правильно, strtok всегда возвращает непустые строки... вероятно, изначально он придумывался для парсинга unix-путей, чтобы отсеивать лишние слеши идущие подряд...
тут или бздяшная strsep, или её ручное исполнение на основе strpbrk...


Название: Re: strtok и много ,,,,,,
Отправлено: _Bers от Декабрь 30, 2015, 01:26
в итоге есть только 3 значения...  Как это победить?

использовать моральный токенайзер.

например:

http://rextester.com/LUPYB81538

Код:
#include <iostream>
#include <string>
 
 
using str = std::string;
 
// определяет регистр букв
enum eCASE { eLOWER = 1<<1, eUPPER =1<<2, eMIXED = 1<<3 };
eCASE checkCase(const char* data, const size_t length);
 
// указатель на функцию-обработчик токена
typedef void callback(const char* data, const size_t length);
 
// вычленяет из текста токены (слова),
// и передает их для дальнейшего анализа
void tokenize(callback func, const str& text, const str& delimiters = " ", bool trimEmpty = false);
 
// функция анализирует обнаруженное слово
void analyze(const char* data, const size_t length);
 
 
int main()
{
    std::cout << "Hello, world!\n";
   
    // токенайзер обнаружит все токены
    // и передаст анализатору каждый из них
    tokenize(analyze, "HELLO hello Hello");
}
 
// анализ токена сводится к тому
// что бы определить в каком регистре
// было записано слово
void analyze(const char* data, const size_t length)
{
    const str word(data, length);
   
    std::cout<<"word '"<<word<<"' is ";
   
    const auto result = checkCase(data, length);
   
    if(result == eLOWER)
        std::cout<<" lower case\n";
    else if(result == eUPPER)
        std::cout<<" upper case\n";
    else
        std::cout<<" mixed case\n";
}
 
// проверяет регистр каждой буковки
// определяя регистр всего токена
eCASE checkCase(const char* data, const size_t length)
{
    int flags = 0;
   
    for(size_t n=0; n<length;++n)
       if( !islower(data[n]) )
           flags |= eUPPER;
       else
           flags |= eLOWER;
       
    if(flags == (eLOWER|eUPPER) )
        return eMIXED;
    else if(flags == eLOWER)
        return eLOWER;
    return eUPPER;
}
 
// по знакам пунктуации находит где начинается и заканчивается очередное слово
// и скармливает его функции-обратного вызова
void tokenize(callback func, const str& text, const str& delimiters, bool trimEmpty)
{
    str::size_type pos, lastPos = 0;
    while(true)
    {
        pos = text.find_first_of(delimiters, lastPos);
       
        if(pos == std::string::npos)
        {
            pos = text.length();
            if(pos != lastPos || !trimEmpty)
                func(text.data()+lastPos, pos-lastPos);
            break;
        }
        else
        {
            if(pos != lastPos || !trimEmpty)
                func(text.data()+lastPos, pos-lastPos);
        }
        lastPos = pos + 1;
    }
}


Название: Re: strtok и много ,,,,,,
Отправлено: Igors от Январь 06, 2016, 13:33
использовать моральный токенайзер.
Что значит (а)"моральный"? И вообще Ваш код меня удивил. Это ж велосипед! А ведь есть готовые решения которые делали умные люди!
Посмотрите на boost::tokenizer или boost::spirit
Вот к чему надо стремиться! А Вы, значит, тот самый "неосилятор"  :) :)


Название: Re: strtok и много ,,,,,,
Отправлено: _Bers от Январь 19, 2016, 19:51
использовать моральный токенайзер.
Что значит (а)"моральный"? И вообще Ваш код меня удивил. Это ж велосипед! А ведь есть готовые решения которые делали умные люди!
Посмотрите на boost::tokenizer или boost::spirit
Вот к чему надо стремиться! А Вы, значит, тот самый "неосилятор"  :) :)

моральный, значит цивилизованный и воспитанный.

код - сэмпл.
кусок годного кода,
который можно точить под себя.
у меня целая гора всяких разных семплов.
часто я не пишу код с нуля, а использую готовые наработки.
(в частности, у меня есть целая коллекция сэплов,
иллюстрирующих работу с boost)

что касается буста - иногда проще скопипастить за минуту сэмпл
из нескольких простейших строк кода,
нежели 4 часа устанавливать буст на машину.

по поводу стремлений,
я практикую технику программирования через страдание:

суть простая: если отсутствие некоторой технологии
не причиняет боль и страдание,
значит эта технология не нужна.

по поводу осиляторства:
слово "значит" обозначает "вывод".
мне не очевидно, на каких основаниях вы сделали вывод
по поводу моего неосилярства.
так же не очевидно, какой "такой".




Название: Re: strtok и много ,,,,,,
Отправлено: Bepec от Январь 19, 2016, 22:24
Хых не ведитесь на его поведение. Это он специально от избытка вредности и прилива антивелосипедности :D


Название: Re: strtok и много ,,,,,,
Отправлено: Igors от Январь 20, 2016, 12:13
я практикую технику программирования через страдание:

суть простая: если отсутствие некоторой технологии
не причиняет боль и страдание,
значит эта технология не нужна.
Ах как Вы хорошо говорите! (иногда). Но как же с пресловутой "общностью"? Что если вместо std::string понадобится напр QString (или что-то еще)?


Название: Re: strtok и много ,,,,,,
Отправлено: Bepec от Январь 20, 2016, 12:29
Igors а вы предусмотрели случай перехода на нечисловую систему измерения? :D
PS предусмотреть всё невозможно. перегружать программу "когдатопонадобится" - к печальному концу программы.


Название: Re: strtok и много ,,,,,,
Отправлено: _Bers от Январь 20, 2016, 19:01
Но как же с пресловутой "общностью"? Что если вместо std::string понадобится напр QString (или что-то еще)?

это противоречит идеи семпла:
быть простым, и понятным примером-иллюстрацией.



Название: Re: strtok и много ,,,,,,
Отправлено: Igors от Январь 21, 2016, 04:11
это противоречит идеи семпла:
быть простым, и понятным примером-иллюстрацией.
Ага, то есть это так, "просто для примера". А вот если "по-взрослому", профессионально - тогда уж точно буст, верно?


Название: Re: strtok и много ,,,,,,
Отправлено: _Bers от Январь 21, 2016, 09:15
Ага, то есть это так, "просто для примера". А вот если "по-взрослому", профессионально - тогда уж точно буст, верно?

не факт.