Russian Qt Forum
Май 21, 2024, 22:23 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: strtok и много ,,,,,,  (Прочитано 8473 раз)
_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 значения...  Как это победить?
« Последнее редактирование: Декабрь 05, 2015, 15:07 от _Vitaliy_ » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Декабрь 05, 2015, 15:44 »

Такие задачки не так уж просты если добросовестно проверять все ошибки. Напр какой рез-т ожидается для
Цитировать
0.17, 6 , 4 3 , , -
?
Если "говнокодить комфортно", то проще всего QString::split (сначала разбить на строки)
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #2 : Декабрь 05, 2015, 16:03 »

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

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

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Fat-Zer
Гость
« Ответ #3 : Декабрь 05, 2015, 19:57 »

всё правильно, strtok всегда возвращает непустые строки... вероятно, изначально он придумывался для парсинга unix-путей, чтобы отсеивать лишние слеши идущие подряд...
тут или бздяшная strsep, или её ручное исполнение на основе strpbrk...
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #4 : Декабрь 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;
    }
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Январь 06, 2016, 13:33 »

использовать моральный токенайзер.
Что значит (а)"моральный"? И вообще Ваш код меня удивил. Это ж велосипед! А ведь есть готовые решения которые делали умные люди!
Посмотрите на boost::tokenizer или boost::spirit
Вот к чему надо стремиться! А Вы, значит, тот самый "неосилятор"  Улыбающийся Улыбающийся
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #6 : Январь 19, 2016, 19:51 »

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

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

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

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

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

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

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


Записан
Bepec
Гость
« Ответ #7 : Январь 19, 2016, 22:24 »

Хых не ведитесь на его поведение. Это он специально от избытка вредности и прилива антивелосипедности Веселый
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Январь 20, 2016, 12:13 »

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

суть простая: если отсутствие некоторой технологии
не причиняет боль и страдание,
значит эта технология не нужна.
Ах как Вы хорошо говорите! (иногда). Но как же с пресловутой "общностью"? Что если вместо std::string понадобится напр QString (или что-то еще)?
Записан
Bepec
Гость
« Ответ #9 : Январь 20, 2016, 12:29 »

Igors а вы предусмотрели случай перехода на нечисловую систему измерения? Веселый
PS предусмотреть всё невозможно. перегружать программу "когдатопонадобится" - к печальному концу программы.
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #10 : Январь 20, 2016, 19:01 »

Но как же с пресловутой "общностью"? Что если вместо std::string понадобится напр QString (или что-то еще)?

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

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Январь 21, 2016, 04:11 »

это противоречит идеи семпла:
быть простым, и понятным примером-иллюстрацией.
Ага, то есть это так, "просто для примера". А вот если "по-взрослому", профессионально - тогда уж точно буст, верно?
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #12 : Январь 21, 2016, 09:15 »

Ага, то есть это так, "просто для примера". А вот если "по-взрослому", профессионально - тогда уж точно буст, верно?

не факт.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.055 секунд. Запросов: 22.