Форум программистов, компьютерный форум CyberForum.ru

Как разделить строку(аналог функции explode) - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
13.01.2014, 21:16     Как разделить строку(аналог функции explode) #1
Есть строка string в которую записаны данные разделенные специальным разделителем например |
Как разделить такую строку и записать полученные данные без разделителя в массив ?

нужна функция на с++ аналог explode на php http://www.php.su/explode

Начал писать

C++
1
2
3
4
5
string msg="1|2|3|4";
string razdelitel="|";
 
size_t pos; 
pos = msg.find(razdelitel);
То есть нашел первое вхождение разделителя в строку, а что дальше делать не пойму, как пройти по всей переменной msg и записать данные разделенные | в массив ?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bend3r
 Аватар для Bend3r
142 / 129 / 17
Регистрация: 29.07.2012
Сообщений: 684
13.01.2014, 21:37     Как разделить строку(аналог функции explode) #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <windows.h>
#include <string.h>
#include <iostream.h>
//----------------------------------------
using namespace std;
 
//------------------------------------------------------------------------------
void main()
{
 
char *buff[] = {"1|2|3|4"};
 
char * p = strtok(buff[0],"|");
while (p!=0)
{
    std::cout << p << '\n';
    p = strtok(NULL,"|");
}
 
 
system("pause");
}
//---------------------------------------------------------------------------
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
13.01.2014, 21:46  [ТС]     Как разделить строку(аналог функции explode) #3
Bend3r, А при чем тут char ? у меня же string
Как тогда преобразовать переменную string в char ?
Bend3r
 Аватар для Bend3r
142 / 129 / 17
Регистрация: 29.07.2012
Сообщений: 684
13.01.2014, 21:49     Как разделить строку(аналог функции explode) #4
Цитата Сообщение от nill Посмотреть сообщение
Bend3r, А при чем тут char ? у меня же string
Как тогда преобразовать переменную string в char ?
C++
1
string str = buff;
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
13.01.2014, 21:53  [ТС]     Как разделить строку(аналог функции explode) #5
Bend3r,
Еще раз, изначально у меня переменная std::string
у нее уже есть значение, откуда я возmму массив char в котором записаны все символы из string???
Bend3r
 Аватар для Bend3r
142 / 129 / 17
Регистрация: 29.07.2012
Сообщений: 684
13.01.2014, 22:17     Как разделить строку(аналог функции explode) #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <windows.h>
#include <string.h>
#include <iostream.h>
//----------------------------------------
using namespace std;
 
//------------------------------------------------------------------------------
void main()
{
string str = "1|2|3|4";
char buff[50];
strcpy(buff,str.c_str());  //присвоение string в char
string massiv[10];      //ваш массив
int q = -1;
char * p = strtok(buff,"|");    //разбитие на лексемы
while (p!=0){                    //проверка
    ++q;
    massiv[q] = p;        //присвоение в массив новой лексемы до '|'
    p = strtok(NULL,"|");       //переход к следующей
}
for (int i = 0; i <= q; i++) {
    cout << massiv[i].c_str() << endl;
}
 
system("pause");
}
Добавлено через 1 минуту
Можно конечно и без strtok, а с помощью find и copy, но можно и так т.к это проверенный способ.
DiffEreD
 Аватар для DiffEreD
1420 / 757 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
13.01.2014, 22:34     Как разделить строку(аналог функции explode) #7
Если имеется boost, то очень просто:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>
 
int main()
{
   std::string s = "1234|5678|ABCD|0000";
   std::vector<std::string> result;
 
   boost::split(result, s, boost::algorithm::is_any_of("|"));
   for(auto& str : result) std::cout << str << "\n";
}
Добавлено через 49 секунд
А иначе надо повозится.

Добавлено через 6 минут
Еще такое надумал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
 
int main()
{
   std::string s = "1234|5678|ABCD|0000";
 
   std::replace(s.begin(), s.end(), '|', ' ');
   std::istringstream iss(s);
   std::vector<std::string> result;
   std::copy(std::istream_iterator<std::string>(iss),
             std::istream_iterator<std::string>(),
             std::back_inserter(result));
 
   for(auto& str : result) std::cout << str << "\n";
}
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
13.01.2014, 22:40  [ТС]     Как разделить строку(аналог функции explode) #8
Bend3r,
Работает только если разделитель из одного символа, а у меня он минимум из 4 символов
попробовал вставить свой разделитель в strtok(); но функция не принимает строку string

DiffEreD,
Спасибо, но пока хочется без boost, как то по простому чтобы
Bend3r
 Аватар для Bend3r
142 / 129 / 17
Регистрация: 29.07.2012
Сообщений: 684
13.01.2014, 22:50     Как разделить строку(аналог функции explode) #9
Цитата Сообщение от nill Посмотреть сообщение
Работает только если разделитель из одного символа, а у меня он минимум из 4 символов
попробовал вставить свой разделитель в strtok(); но функция не принимает строку string
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <windows.h>
#include <string.h>
#include <iostream.h>
//----------------------------------------
using namespace std;
 
//------------------------------------------------------------------------------
void main()
{
string str = "Hello1234kak dela1234ahah1234";
char buff[50];
strcpy(buff,str.c_str());  //присвоение string в char
string massiv[10];      //ваш массив
int q = -1;
char * p = strtok(buff,"1234");    //разбитие на лексемы
while (p!=0){                    //проверка
    ++q;
    massiv[q] = p;        //присвоение в массив новой лексемы до '|'
    p = strtok(NULL,"1234");       //переход к следующей
}
for (int i = 0; i <= q; i++) {
    cout << massiv[i].c_str() << endl;
}
 
system("pause");
}
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
13.01.2014, 23:07  [ТС]     Как разделить строку(аналог функции explode) #10
Bend3r,
Моя ошибка, не заметил у тебя там два раза нужно вводить разделитель. Все работает!
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
16.01.2014, 00:01  [ТС]     Как разделить строку(аналог функции explode) #11
Bend3r,

С функцией проблема
она не работает если разделитель не писать текстом "1234", а передавать через переменную
C++
1
2
3
4
5
6
7
8
9
10
11
12
string razdelitel="1234";
char razdelitel_ch[5];
strcpy(buff,str.c_str());  //присвоение string в char
strcpy(razdelitel_ch,razdelitel.c_str());  //присвоение string в char
 
    int q = -1;
    char * p = strtok(buff,razdelitel_ch);    //разбитие на лексемы
    while (p!=0){                    //проверка
        ++q;
        result_mass[q] = p;        //присвоение в массив новой лексемы до '|'
        p = strtok(NULL,razdelitel_ch);       //переход к следующей
    }
И еще даже если писать разделитель тестом, то функция работает с ошибкой, она разделяет строку даже когда встретит какой то один символ из тех что входят в разделитель, а нужно делить только когда встречаются все символы которые входят в разделитель.

Подскажи плз что не так и как исправить ?

Написал свою функцию все работает,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
string explode(string text, string razdelitel, string result_mass[200]){
    string result;
    int i=0, n=0, j=0;
 
    //_cprintf(" text= %s", text.c_str());_cprintf("\n");
 
 
    for (i=0; i<sizeof(result_mass); i++){result_mass[i]="";}
    char text_ch[65535];
    char razdelitel_ch[15];
 
    strcpy(text_ch, text.c_str()); 
    strcpy(razdelitel_ch, razdelitel.c_str());
    ev_time_start =clock();
    for (i=0; i<sizeof(text_ch); i++){
        if(text_ch[i]==0){break;}
        if(text_ch[i]==razdelitel_ch[0]&&text_ch[i+1]==razdelitel_ch[1]&&text_ch[i+2]==razdelitel_ch[2]&&text_ch[i+3]==razdelitel_ch[3]){
 
 
            for (j=i+4; j<sizeof(text_ch); j++){
 
                if(text_ch[j]==razdelitel_ch[0]&&text_ch[j+1]==razdelitel_ch[1]&&text_ch[j+2]==razdelitel_ch[2]&&text_ch[j+3]==razdelitel_ch[3]){n++;break;}
 
 
                result_mass[n]=result_mass[n]+text_ch[j];
                i=j;
            }}}
    ev_time_end =clock();
    ev_time = (double)(ev_time_end-ev_time_start)/1000;
    _cprintf("sikl:%f ", ev_time);_cprintf("sec");_cprintf("\n");
 
    return result;
}
но медленно около 2 сек на 1 функцию и хотелось бы отладить твой быстрый способ.
Bend3r
 Аватар для Bend3r
142 / 129 / 17
Регистрация: 29.07.2012
Сообщений: 684
16.01.2014, 17:59     Как разделить строку(аналог функции explode) #12
Цитата Сообщение от nill Посмотреть сообщение
Bend3r, С функцией проблема
она не работает если разделитель не писать текстом "1234", а передавать через переменную
Вы как всегда не внимательны. Вот я вам переделал чтоб разделитель был в виде переменной.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <windows.h>
#include <string.h>
#include <iostream.h>
//----------------------------------------
using namespace std;
 
//------------------------------------------------------------------------------
void main()
{
string str = "Hello1234kak dela1234ahah1234";
string razdel = "1234";
char buff[50];
strcpy(buff,str.c_str());  //присвоение string в char
string massiv[10];      //ваш массив
int q = -1;
char * p = strtok(buff,razdel.c_str());    //разбитие на лексемы
while (p!=0){                    //проверка
    ++q;
    massiv[q] = p;        //присвоение в массив новой лексемы до '|'
    p = strtok(NULL,razdel.c_str());       //переход к следующей
}
for (int i = 0; i <= q; i++) {
    cout << massiv[i].c_str() << endl;
}
 
system("pause");
}
Добавлено через 7 минут
По поводу того как решить проблему, если встречается первый символ разделителя и он разделяет, я пока думаю, но возможно этот способ и не подойдет. А так лучше разберитесь с регулярными выражениями.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.01.2014, 13:46     Как разделить строку(аналог функции explode)
Еще ссылки по теме:

C++ Разделить строку на строку и переменную
Как разделить строку на слова? C++
Как лучше всего разделить строку на несколько подстрок? C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
nill
8 / 8 / 0
Регистрация: 16.08.2009
Сообщений: 417
17.01.2014, 13:46  [ТС]     Как разделить строку(аналог функции explode) #13
Bend3r,
Сейчас проверил, передача разделителя в функцию через переменную работает, а если встречается символ разделителя опять то же самое.

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

С регулярными выражениями я еще больше буду разбираться лучше как то отладить одну из двух функций.

Добавлено через 17 часов 37 минут
В общем разобрался сам
использовать преобразование char в string было ошибкой нужно использовать функции самого string

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void explode_string(string str, string razdelitel, string result_mass[200]){
 
    int dlinna_razdelitela=razdelitel.length();
    size_t pos;
    size_t pos1;
    int n=0, ot=0, doo=0, dlinna=0;
 
    for (int i=0; i<str.length(); i++){
 
        pos = str.find(razdelitel, i);
        if (pos != string::npos){
 
            pos1 = str.find(razdelitel, pos+1);
 
            ot=pos+dlinna_razdelitela;
            doo=pos1;
            dlinna=doo-ot;
 
            if (pos1 != string::npos){result_mass[n] = str.substr (ot,dlinna);}
            else{result_mass[n] = str.substr (ot);}
 
            n++;
            
 
            i=pos+dlinna_razdelitela;}
 
    }
 
}
Yandex
Объявления
17.01.2014, 13:46     Как разделить строку(аналог функции explode)
Ответ Создать тему
Опции темы

Текущее время: 00:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru