Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбить слова строки на масивы 
:(
    Опции темы
HeyThere
Дата 3.3.2013, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 1.3.2013

Репутация: нет
Всего: нет



Есть строка типа "тест1,тест34,,фыв", требуется разбить ее на массив с элементами "тест1", "тест34", "", "фыв". Как организовать? Может есть у кого готовые алгоритмы...
PM MAIL   Вверх
NoviceF
Дата 3.3.2013, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: 2
Всего: 2



Есть вот такая заготовка:

Код

    string delim = " -";
    
    string str = "This is - a simple string";

    std::vector<std::string> vecRes;
    
    std::size_t              curPos = 0;    //start of string    
    std::size_t              oldPos = 0;    //start of string
   
    while (string::npos != (curPos = str.find_first_of(delim, oldPos))) 
    {
        vecRes.push_back(str.substr(oldPos, curPos - oldPos));
        oldPos = curPos + 1;
    }        
    vecRes.push_back(str.substr(oldPos, string::npos));


Это сообщение отредактировал(а) NoviceF - 3.3.2013, 19:50
PM MAIL   Вверх
fish9370
Дата 3.3.2013, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



функция на Си подойдет?

внимание: первоначальная строка будет уничтожена (нужно копировать)

Код

int split_words_marker(char *buff, char *ap[], char marker, int size)
{
        if (!buff)
                return 0;
        int n = 0;

        char *pos = buff;
        ap[n++] = pos;

        while (*pos) {
                if (n == size - 1)
                        break;

                if (*pos == marker) {
                        *pos = '\0';
                        ap[n++] = ++pos;
                } else
                        pos++;
        }

        ap[n] = NULL;

        return n;
}


использование:

Код

#define MAX_WORDS 256
                char buff_1[4096];
                char *buffv[MAX_WORDS];

                strncpy(buff_1, "тест1,тест34,,фыв", sizeof(buff_1));

                int n = split_words_marker(buff_1, buffv, ',', MAX_WORDS);

                printf("result: ");
                for(i = 0; i < n; i++)
                                printf("%s ", buffv[i]);



Это сообщение отредактировал(а) fish9370 - 3.3.2013, 19:51


--------------------
undefined
PM MAIL WWW ICQ   Вверх
bsa
Дата 4.3.2013, 10:30 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



NoviceF, через std::getline будет проще  smile 
fish9370, а разве не для этого strtok существует  smile 
PM   Вверх
fish9370
Дата 4.3.2013, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(bsa @  4.3.2013,  10:30 Найти цитируемый пост)
fish9370, а разве не для этого strtok существует


Эта функция немного другая, 

Код

char *strtok_r(char *s, const char *delim, char **ptrptr); 


более похожа на мою, я только не могу понять, размерность ptrptr, если токенов окажется больше чем я выделю под ptrptr?


--------------------
undefined
PM MAIL WWW ICQ   Вверх
xvr
Дата 4.3.2013, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(fish9370 @  4.3.2013,  11:40 Найти цитируемый пост)
strtok_r - более похожа на мою, я только не могу понять, размерность ptrptr, если токенов окажется больше чем я выделю под ptrptr? 

У prtprt размерности нет - это указатель на переменную типа char*
Цитата

The strtok_r() function is a reentrant version strtok(). The saveptr argument is a pointer to a char * variable that is used internally by strtok_r() in order to maintain context between successive calls that parse the same string.

On the first call to strtok_r(), str should point to the string to be parsed, and the value of saveptr is ignored. In subsequent calls, str should be NULL, and saveptr should be unchanged since the previous call.

Different strings may be parsed concurrently using sequences of calls to strtok_r() that specify different saveptr arguments. 

Conforming To

strtok_r()
    POSIX.1-2001. 

Так что это не та функция.
И вообще strtok с сотоварищами ТС не подойдет - она трактует повторяющиеся разделители как один, а ТС нужно отработать каждый по отдельности  smile 

PM MAIL   Вверх
fish9370
Дата 4.3.2013, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(xvr @  4.3.2013,  13:37 Найти цитируемый пост)
У prtprt размерности нет - это указатель на переменную типа char*


да нет судя по объявлению, это указатель на *char (короче char **ptrptr), значит должна быть размерность..

я не помню, почему я не стал пользоваться этой функцией..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
bsa
Дата 4.3.2013, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



fish9370, что значит размерность? sizeof(char*) - вот такая размерность. Ей нужно лишь указатель на переменную, в которой она будет хранить текущую позицию в строке.
PM   Вверх
fish9370
Дата 4.3.2013, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(bsa @  4.3.2013,  13:46 Найти цитируемый пост)
что значит размерность? sizeof(char*) - вот такая размерность


мне вопрос на самом деле не совсем понятен, char** - массив указателей, у массива есть размерность.. или мы друг друга не понимаем?


--------------------
undefined
PM MAIL WWW ICQ   Вверх
xvr
Дата 4.3.2013, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(fish9370 @  4.3.2013,  13:51 Найти цитируемый пост)
мне вопрос на самом деле не совсем понятен, char** - массив указателей, у массива есть размерность.. 

Видимо не только у Буратино проблемы с количеством звездочек  smile 
char** - это совсем не обязательно массив указателей. В данном случае это указатель на одну скалярную переменную.
Код

char* save_ptr;

char* res=strtok_r(buffer,"\n",&save_ptr);
char* res2=strtok_r(NULL,"\n",&save_ptr);
// ну и т.д. и т.п.


PM MAIL   Вверх
fish9370
Дата 4.3.2013, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



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


--------------------
undefined
PM MAIL WWW ICQ   Вверх
xvr
Дата 4.3.2013, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(fish9370 @  4.3.2013,  14:12 Найти цитируемый пост)
да, с примером, все стало на свои места, на мой взгляд, это неудобно.. требуются дополнительные операции по извлечению строки..

Ну в общем да - неудобно. И шурупы молотком забивать неудобно  smile 
Эта функция была сделанна как замена strtok, которая в свою очередь появилась еще в K&R времена, и была предназначенна исключительно для последовательного разбиения строки на части. 
Для функции, которая могла бы выдать сразу все разбиение в виде массива, понадобилось бы где то создать массив, причем заранее неизвестного размера. Так что по частям оно гораздо проще (да и гибче - например параметр delim может от вызова к вызову меняться  smile )

PM MAIL   Вверх
fish9370
Дата 4.3.2013, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(xvr @  4.3.2013,  14:27 Найти цитируемый пост)
Так что по частям оно гораздо проще


не соглашусь - мало того это ненужная работа,

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

Код

Z;21234027;04.03.13;15:39:26;15:39:27;79;78;4997068036;84955392670;22;0665;21;0636;90;0;1


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

назовите хоть одно приемущество strtok_r  smile 

Цитата(xvr @  4.3.2013,  14:27 Найти цитируемый пост)
да и гибче - например параметр delim может от вызова к вызову меняться


а зачем?  smile 



--------------------
undefined
PM MAIL WWW ICQ   Вверх
bsa
Дата 4.3.2013, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(fish9370 @  4.3.2013,  15:39 Найти цитируемый пост)
назовите хоть одно приемущество strtok_r 
она уже есть и писать ее не надо.
А потом, чтобы распарсить всю эту строку, тебе необходимо по ней пробежаться в любом случае. strtok позволяет это сделать:
Код
for(char *tmp, *res = strtok(data, ';', &tmp); res; res = strtok(NULL, ';', &tmp), ++i)
   strcpy(array[i], res);

PM   Вверх
fish9370
Дата 4.3.2013, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(bsa @  4.3.2013,  17:27 Найти цитируемый пост)
она уже есть и писать ее не надо


это я не понял


Цитата(bsa @  4.3.2013,  17:27 Найти цитируемый пост)
А потом, чтобы распарсить всю эту строку, тебе необходимо по ней пробежаться в любом случае. strtok позволяет это сделать:


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

плюс выполняешь дополнительное копирование..
и копирование не совсем чистое, может быть переполнение буфера.. т.е. в конечном варианте, все может еще немного измениться в коде..

Это сообщение отредактировал(а) fish9370 - 4.3.2013, 17:52


--------------------
undefined
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1157 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.