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

Разбор строки - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 34, средняя оценка - 4.71
xaker1
7 / 7 / 0
Регистрация: 21.02.2011
Сообщений: 80
29.03.2011, 22:54     Разбор строки #1
Здравствуйте.
В stdin программы приходит строка вида domain=d.ru&type=delete&file=std&...
При этом мне необходимо получить значение domain и type. По type нужно выбрать нужное действие (case).
Собственно проблема с разбором строки, приходящей на stdin (в php есть замечательная функция explode(), аналога которой в c++ я не нашел). Получаю я ее с помощь
C++
1
2
3
4
5
6
int main()
{
    string input;
    getline(cin,input); 
...
}
Максимум чего смог добиться - разделение строки по & с помощью следующего кода:
C++
1
2
3
4
5
6
7
8
9
    char* url = new char[input.length()];
    strcpy(url, input.c_str());
 
    char*v=strtok(url,"&"); 
    while (v!=0)
    {
        cout<<v;
        v=strtok(0,"&");
    }
Подскажите, как можно распарсить входную строку.
p.s. А массивы в c++ поддерживают строковые ключи mass[domain] или только числовые mass[14]?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
30.03.2011, 00:17     Разбор строки #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
24
25
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
 
int main() {
   std::string src = "domain=d.ru&type=delete&file=std";
   std::string tmp;
   std::vector<std::string> svec;
   std::istringstream is(src);
   while ( std::getline(is, tmp, '&') ) {
      svec.push_back(tmp);
   }
   
   for ( std::vector<std::string>::const_iterator iter = svec.begin(); iter != svec.end(); ++iter ) {
      std::istringstream is(*iter);
      std::string left, right;
      std::getline(is, left, '=');
      std::getline(is, right, '=');
      
      std::cout << left << " : " << right << std::endl;
   }
}
http://liveworkspace.org/code/83ef75...8be3abbc08ddc4
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
30.03.2011, 00:34     Разбор строки #3
ещё
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<string>
 
void extract(const std::string& mes, std::string& res){
    std::string::size_type i1, i2;
    if((i1=mes.find(res))!=std::string::npos&&((i2=mes.find('&', i1))!=std::string::npos)){
        res.assign(&mes[i1+res.size()], &mes[i2]);
    }
}
 
int main(){
    std::string mes="domain=d.ru&type=delete&file=std&...", domain="domain=", type="type=";
    extract(mes, domain);
    extract(mes, type);
    std::cout<<domain<<"\n"<<type<<"\n";
}
Добавлено через 19 секунд
ещё
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<string>
 
void extract(const std::string& mes, std::string& res){
    std::string::size_type i1, i2;
    if((i1=mes.find(res))!=std::string::npos&&((i2=mes.find('&', i1))!=std::string::npos)){
        res.assign(&mes[i1+res.size()], &mes[i2]);
    }
}
 
int main(){
    std::string mes="domain=d.ru&type=delete&file=std&...", domain="domain=", type="type=";
    extract(mes, domain);
    extract(mes, type);
    std::cout<<domain<<"\n"<<type<<"\n";
}
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
30.03.2011, 01:13     Разбор строки #4
Цитата Сообщение от xaker1 Посмотреть сообщение
А массивы в c++ поддерживают строковые ключи mass[domain] или только числовые mass[14]?
ассоциативные контейнеры - map, set & etc.
xaker1
7 / 7 / 0
Регистрация: 21.02.2011
Сообщений: 80
30.03.2011, 15:03  [ТС]     Разбор строки #5
То ли я чего-то не понимаю, то ли еще не проснулся.
Мой код:
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
34
35
36
37
38
#include<fstream>
#include<iostream>
#include<string>
 
using namespace std;
 
void extract(const string& mes, const string& res, string& edit){
    string::size_type i1, i2;
    if((i1=mes.find(res))!=string::npos&&((i2=mes.find('&', i1))!=string::npos)){
        edit.assign(&mes[i1+res.size()], &mes[i2]);
    }
}
 
int main(){
    // Объявляем переменные
    string input,domain,alias,func;
    //const char* file_name = "/usr/local/ispmgr/etc/domains.ban.list";
    const char* file_name = "ban.txt";
    char load_string[183];
    char domains[183];
    char keys[256];
    char value[256];
    cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<doc>\n";
 
 
    getline(cin,input);
 
    extract(input, "domain=",domain);
    extract(input, "func=",func);
    extract(input, "alias=",alias);
 
    cout<<domain<<" "<<func<<" "<<alias<<"\n";
 
    //f.close();
    system("pause");
    cout <<"</doc>\n";
    return 0;
}
На вход даю строку
domain=yandex.ru&alias=ya.ru&func=wwwdomain.edit
Выводит только два значения из stdin. В чем может быть загвостка?
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
30.03.2011, 17:01     Разбор строки #6
Цитата Сообщение от xaker1 Посмотреть сообщение
В чем может быть загвостка?
в конце входной строки нет &. Вот так будет работать
C++
1
2
3
4
5
6
7
void extract(const string& mes, const string& res, string& edit){
    string::size_type i1, i2;
    if((i1=mes.find(res))!=string::npos){
        if((i2=mes.find('&', i1))==string::npos) i2=mes.size();
        edit.assign(&mes[i1+res.size()], &mes[i2]);
    }
}
afiskon
 Аватар для afiskon
65 / 53 / 3
Регистрация: 06.09.2010
Сообщений: 254
30.03.2011, 17:18     Разбор строки #7
Заюзать библиотеку для регулярных выражений.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
30.03.2011, 18:07     Разбор строки #8
контейнер со строковыми мультиключами
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include<sstream>
#include<string>
#include<map>
using namespace std;
 
int main(){
    string input="domain=yandex.ru&alias=ya.ru&func=wwwdomain.edit", key, value;
    for(int i=0; i<input.size(); ++i){
        if(input[i]=='='||input[i]=='&') input[i]=' ';
    }
    stringstream ss(input);
    multimap<string, string> con;
    while(ss>>key&&ss>>value){
        con.insert(make_pair(key, value));
    }
    multimap<string, string>::const_iterator it;
    if((it=con.find("domain"))!=con.end()) cout<<(*it).second<<"\n";
    if((it=con.find("alias"))!=con.end()) cout<<(*it).second<<"\n";
    if((it=con.find("func"))!=con.end()) cout<<(*it).second<<"\n";
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.03.2011, 19:40     Разбор строки
Еще ссылки по теме:

Разбор сложной строки с аргументами C++
Разбор выражений C++
C++ Разбор командной строки\Вывод в файл координат

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

Или воспользуйтесь поиском по форуму:
xaker1
7 / 7 / 0
Регистрация: 21.02.2011
Сообщений: 80
30.03.2011, 19:40  [ТС]     Разбор строки #9
Всем спасибо, разобрался. Ну и последний вопрос, косвенно касающийся данной темы (оба вопроса всплыли в ходе решения одной и той же задачи). Каким образом можно в stdout выдать строку в utf8?
Yandex
Объявления
30.03.2011, 19:40     Разбор строки
Ответ Создать тему
Опции темы

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