Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/35: Рейтинг темы: голосов - 35, средняя оценка - 4.94
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
1

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

13.01.2014, 21:16. Показов 6713. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть строка 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 и записать данные разделенные | в массив ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.01.2014, 21:16
Ответы с готовыми решениями:

Есть ли в С аналог функции explode(или split)?
Есть ли в С аналог или сама функция explode или split, которая позволяет разбить строку на...

Аналог explode или как еще распарсить строку
Подскажите, есть ли в дельфи аналог php-функции explode? После запроса мне приходит ответ от...

Аналог php'шной функции explode()?
Есть ли в Дельфи 7 аналог php'шной функции explode() ? Описание функции: explode Разделение...

Как разделить строку на подстроки, без использования функции Split
Подскажите, как разделить строку на подстроки, без использования метода Split. Есть идеи что...

12
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
13.01.2014, 21:37 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");
}
//---------------------------------------------------------------------------
1
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
13.01.2014, 21:46  [ТС] 3
Bend3r, А при чем тут char ? у меня же string
Как тогда преобразовать переменную string в char ?
0
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
13.01.2014, 21:49 4
Цитата Сообщение от nill Посмотреть сообщение
Bend3r, А при чем тут char ? у меня же string
Как тогда преобразовать переменную string в char ?
C++
1
string str = buff;
0
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
13.01.2014, 21:53  [ТС] 5
Bend3r,
Еще раз, изначально у меня переменная std::string
у нее уже есть значение, откуда я возmму массив char в котором записаны все символы из string???
0
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
13.01.2014, 22:17 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, но можно и так т.к это проверенный способ.
1
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
13.01.2014, 22:34 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";
}
0
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
13.01.2014, 22:40  [ТС] 8
Bend3r,
Работает только если разделитель из одного символа, а у меня он минимум из 4 символов
попробовал вставить свой разделитель в strtok(); но функция не принимает строку string

DiffEreD,
Спасибо, но пока хочется без boost, как то по простому чтобы
0
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
13.01.2014, 22:50 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");
}
1
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
13.01.2014, 23:07  [ТС] 10
Bend3r,
Моя ошибка, не заметил у тебя там два раза нужно вводить разделитель. Все работает!
0
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
16.01.2014, 00:01  [ТС] 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 функцию и хотелось бы отладить твой быстрый способ.
0
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
16.01.2014, 17:59 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 минут
По поводу того как решить проблему, если встречается первый символ разделителя и он разделяет, я пока думаю, но возможно этот способ и не подойдет. А так лучше разберитесь с регулярными выражениями.
1
11 / 11 / 2
Регистрация: 16.08.2009
Сообщений: 434
17.01.2014, 13:46  [ТС] 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;}
 
    }
 
}
1
17.01.2014, 13:46
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2014, 13:46
Помогаю со студенческими работами здесь

explode разделяет строку не так как надо, по символу "\n" конца строки
почему этот код разделяет строку не так как надо, т.е. по символу &quot;\n&quot; конца строки. а разбивает в...

Перевести строку в число (аналог функции StrToInt)
В singleedit введено число, но как объяснить билдеру что это число? Это необходимо для поиска. В...

Работа функции explode
Уже около часа думаю над такой вот проблемой. В коде необходимо разделить строку по разделителю,...

P-CAD - сборка элемента после функции Explode.
Всем добрый день! У меня есть проект, в котором одна микросхема на 316 ножек была разбита на 7...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru