7 / 7 / 1
Регистрация: 07.05.2013
Сообщений: 136
1

Как распарсить строку и положить данные в элементы структуры

07.05.2013, 11:13. Показов 3801. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
Интересует следующий вопрос. У нас есть есть строка. Например, ab|ac|ad|ae|af|ag|ah. И есть структура ->
C++
1
2
3
4
struct table
{
string ab, ac, ad, ae, af, ag, ah;
};
Задача состоит в том, чтобы из строки вытащить значения, какими являются ab, ac, .., ah. Я написал кусок кода, который вытаскивает эти значения. Но т.к. это дело происходит в цикле, я не могу на каждом шаге записать значение в элемент структуры. По идее должно быть так
C++
1
2
3
4
table.ab = "ab";
table.ac = "ac";
...
table.ah = "ah";
На всякий случай приведу пример куска кода. Прошу особо не ругаться, потому что для меня сейчас важно, что это работает.
C++
1
2
3
4
5
6
7
8
    while(str.length() > 0)
    {
        len = str.copy(str2, '|' - 1, 0); // str - это и есть строка, которую нужно разбить на части
        str2[len] = '\0';
        str3.assign(str2, str.find('|')); // str3 - это это часть строки, которую нужно вытащить
        table.ab = str3; // вот здесь вся загвоздка
        str.erase(0, str.find('|') + 1);
    }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.05.2013, 11:13
Ответы с готовыми решениями:

Как положить строку из файла в контейнер vector
Нужно считать строки из файла, и все строки, начинающиеся на "a, c, e..." в контейнер vector...

Распарсить строку и записать данные в массив
Как строку {оваться,у{йся,йтесь},у{юсь,ешься,ется,емся,етесь,ются,ясь},ова{лся,лась,лось,лись}} ...

Распарсить строку и разнести данные по двум ListBox
Есть текстовый файл, с определёнными данными. В 11 строке данные которые нам нужны разделены ";"....

Распарсить строку и записать полученные данные в двумерный массив
необходимо разобрать строку в двумерный массив . строка вида ,]

8
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.05.2013, 11:17 2
FacelessShadow, Никак. Каждый раз вручную понимать что именно сейчас считывается. Ну или сделать итератор по полям, но это уже несколько сложнее и не стоит оно того.
Если порядок установлен - просто считывайте без цикла в поля по порядку и все.
0
7 / 7 / 1
Регистрация: 07.05.2013
Сообщений: 136
07.05.2013, 11:23  [ТС] 3
ForEveR, порядок то установлен. Просто интересно, а если бы было, например, 20-30 полей?
Ладно. Тогда буду действовать в ручную
Спасибо!
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.05.2013, 11:28 4
FacelessShadow,
порядок то установлен. Просто интересно, а если бы было, например, 20-30 полей?
Пишем функцию, которая считывает значение - вызываем для каждого поля по порядку - профит.
0
7 / 7 / 1
Регистрация: 07.05.2013
Сообщений: 136
07.05.2013, 11:36  [ТС] 5
ForEveR, ну это 20 однотипных строчек.. не есть хорошо ведь. Хотя в такой ситуации выход только один
0
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
07.05.2013, 11:48 6
Проще сделай массив из записей. И туда записывай.

C++
1
2
table mas[10];
mas[i].ab='ac'; //ну как тебе надо.
Но добавь еще переменную i. И при каждой итерации делай i++;
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
07.05.2013, 12:23 7
FacelessShadow, Ну почему же один...

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/algorithm/string.hpp>
 
#include <iostream>
 
struct table
{
   std::string ab, ac, ad;
};
 
BOOST_FUSION_ADAPT_STRUCT
(
   table,
   (std::string, ab)
   (std::string, ac)
   (std::string, ad)
);
 
namespace fusion = boost::fusion;
 
template<typename Iterator, typename Last>
struct assign_helper
{
   template<typename WordIterator>
   static void apply (Iterator current, WordIterator pos)
   {
      fusion::deref(current) = *pos;
      assign_helper<typename fusion::result_of::next<Iterator>::type, Last>::
         apply(fusion::next(current), ++pos);
   }
};
 
template<typename Last>
struct assign_helper<Last, Last>
{
   template<typename WordIterator>
   static void apply (Last, WordIterator)
   {
   }
};
 
table assign(const std::vector<std::string>& v)
{
   table t;
   std::vector<std::string>::const_iterator pos = v.begin();
   assign_helper<typename fusion::result_of::begin<table>::type,
      typename fusion::result_of::end<table>::type>::
      apply(fusion::begin(t), pos);
   return t;
}
 
int main()
{
   const std::string res = "ab|ac|ad";
   std::vector<std::string> vec;
   boost::split(vec, res, boost::is_any_of("|"), boost::token_compress_on);
   table t = assign(vec);
   std::cout << t.ab << " " << t.ac << " " << t.ad << std::endl;
}
Bash
1
2
forever@pterois:~/My_projects/cpp_pro$ ./new
ab ac ad
Только вот надо-ли вам оно?)
1
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
07.05.2013, 20:16 8
Не знаю насколько это актуально, но сделал на основе регулярных выражений:
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
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <boost/regex.hpp>
 
struct table
{
    std::vector<std::string> vs;
};
 
int main() 
{
    std::ifstream ifs("D:/file.txt");
    if (ifs.is_open())
    {
        std::string s((std::istreambuf_iterator<char>(ifs.rdbuf())), std::istreambuf_iterator<char>());
        std::vector<table> vt;
        boost::regex reg("^(\\w+\\|){6}\\w+$");  //фильтруем строку нужного формата
    
        for (boost::sregex_iterator i(s.begin(), s.end(), reg); i != boost::sregex_iterator(); ++i)
        {
            std::string line = (*i)[0];
            static boost::regex reg_in("(\\w+)"); //ищем совпадения
            table temp_tb;
            for (boost::sregex_iterator j(line.begin(), line.end(), reg_in); j != boost::sregex_iterator(); ++j)
            {
                temp_tb.vs.push_back((*j)[0]);
            }
            vt.push_back(std::move(temp_tb));
        } 
            
        for (const auto& i : vt)
        {
            for (const auto& j : i.vs) std::cout<<j<<" ";
                std::cout<<std::endl;
        }
    }
    else
        std::cerr << "Unable to open file\n";
    
    return 0;
}
Входные данные (с возможным мусором в строках, которые будут пропускаться):
aa|ab|ac|ad|ae|af|ag
ba|bb|bc|bd|be|bf|bg
ca|cb|cc|cd|ce|cf|cg
0
7 / 7 / 1
Регистрация: 07.05.2013
Сообщений: 136
09.05.2013, 12:33  [ТС] 9
Спасибо за ответы. Для саморазвития отложу в папочку. Но в данный момент так заморачиваться не стоит.
0
09.05.2013, 12:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.05.2013, 12:33
Помогаю со студенческими работами здесь

Распарсить строку на элементы и занести в массив
В общем возвращаясь к непонятному для меня PHP. Как вы в этом языке парсите строки...

Как положить значения в строку
Приветствую! Помогите пожалуйста найти решение: имеется переменная $randomName, которая содержит 6...

Как данные положить в див списком?
Ребят есть &lt;div id=&quot;content&quot;&gt;&lt;/div&gt; Есть приходящий Ajax в котором к примеру data: 0: {id:...

Как положить double в строку типа TCHAR
Здравствуйте. Есть число double. Нужно положить его в строку типа TCHAR и вывести. Пример...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

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