Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
#1

TinyXML. Преобразовать TiXmlElement в TiXmlString, char[] или string - C++

17.05.2014, 10:10. Просмотров 1399. Ответов 25
Метки нет (Все метки)

Вообщем-то, задача проста (для тех, кто работал с библиотекой TinyXML). Но я первый раз с ней работаю, и вообще первый раз со сторонними библиотеками.
Имеется: объект, содержащий данные XML-тега (получено с помощью метода FirstChildElement, сохранено в объект типа TiXmlElement).
Нужно: преобразовать или в string (лучше всего), или в массив char или в TiXmlString (последний вариант, тогда нужно TiXmlString в string перевести).

Заранее спасибо за помощь.

Добавлено через 9 минут

Выложил ниже main() - точку входа. Коротенько опишу класс Sum. Имеет поля "сумма", "буквенный код", "курс доллара". Без полиморфизма и наследования.
Кликните здесь для просмотра всего текста
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
int main()
{
    setlocale(0, "");
 
    float any2rur, to_usd_into_rur;
    Sum s1(500, 8.5, "UAH");
 
    TiXmlDocument *xml_MAIN = new TiXmlDocument("XML_daily.asp.xml");
    if(!xml_MAIN->LoadFile())
        return 1;
    TiXmlElement *xml_ValCurs = 0;
    TiXmlElement *xml_Valute = 0;
    TiXmlElement *xml_CharCode = 0;
    TiXmlElement *xml_Name = 0;
    TiXmlElement *xml_Value = 0;
 
    xml_ValCurs = xml_MAIN->FirstChildElement("ValCurs");
    xml_Valute = xml_ValCurs->FirstChildElement("Valute");
    xml_CharCode = xml_Valute->FirstChildElement("CharCode");
    //delete xml_CharCode;
    xml_Name = xml_Valute->FirstChildElement("Name");
    //delete xml_Name;
    xml_Value = xml_Valute->FirstChildElement("Value");
 
    string str1 = (string)xml_CharCode; //вот это организовать
    string str2 = s1.GetCode();
 
    while(xml_Valute != NULL)
    {
         if(str1 != str2) //для этого условия сравнения string
        {
            xml_Valute = xml_Valute->NextSiblingElement("Valute");
        }
        xml_Value->QueryFloatAttribute("Value", &any2rur);
    }
    //cout << &any2rur;
}


Добавлено через 10 часов 35 минут
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.05.2014, 10:10
Здравствуйте! Я подобрал для вас темы с ответами на вопрос TinyXML. Преобразовать TiXmlElement в TiXmlString, char[] или string (C++):

Преобразовать const unsigned char* в std::string (или _bstr_t ) - C++
Здравствуйте старшие товарищи! Есть функция, которая возвращает результат типа const unsigned char*. а мне нужно получить ...

Как преобразовать char* в string и вывести переменную string на экран? - C++
for (int k = 0; k &lt; 10; k++) { int x = (int)rand() / RAND_MAX + rand() % 6 + 2; char *chars = new char; ...

Не удаётся преобразовать string в char - C++
Здравствуйте. Пользуюсь C++Builder. Создана форма с тремя TEdit + кнопка. Задача, при вводе в TEdit1 и TEdit2 числовых значений, ...

Преобразовать string в массив char - C++
Всем доброго времени суток!Как преобразовать string в массив char.

преобразовать программу из string в char - C++
Помогите преобразовать программу из string в char #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;fstream&gt; ...

Как преобразовать char в string - C++
Есть массив char buffer; есть переменная string X; как присвоить значение X допустим такое X=buffer+buffer;

25
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
17.05.2014, 12:59 #2
NewEXE, http://sourceforge.net/projects/rapidxml/files/latest/download попробуй это.

Добавлено через 1 минуту
А также прочти это http://stackoverflow.com/questions/170686/best-open-xml-parser-for-c
0
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
17.05.2014, 14:16  [ТС] #3
outoftime, Вы предлагаете мне полностью разобраться с другим парсером, вместо того, чтобы разобраться с одной-двумя функциями TinyXML?
0
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
17.05.2014, 21:35 #4
NewEXE, выложи весь исходный код с makefile-ом.

Добавлено через 21 минуту
Цитата Сообщение от NewEXE Посмотреть сообщение
string str1 = (string)xml_CharCode; //вот это организовать
Что ты хочешь получить на выходе? Тебе нужен только внутренний текст?

Добавлено через 4 минуты
В общем подход один и тот же.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <tinyxml.h>
#include <string>
#include <iostream>
 
using namespace std;
 
int main()
{
    TiXmlDocument *xml_MAIN = new TiXmlDocument("XML_daily.asp.xml");
    TiXmlElement *xml_ValCurs = 0;
    TiXmlElement *xml_Valute = 0;
    TiXmlElement *xml_CharCode = 0;
 
    xml_ValCurs = xml_MAIN->FirstChildElement("ValCurs");
    xml_Valute = xml_ValCurs->FirstChildElement("Valute");
    xml_CharCode = xml_Valute->FirstChildElement("CharCode");
    
    const char* text = xml_CharCode->GetText();
    string str1(text, text + strlen(text));
}
Добавлено через 54 секунды
NewEXE, идет?
1
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
18.05.2014, 01:34  [ТС] #5
outoftime, да, мне всего лишь нужен был "внутренний текст", я его получил. Но это, как ни странно, не помогло мне решить мою задачу
cout << &any2rur выводит неверное значение, вернее, какой-то (?)адрес. Он должен вывести значение "гривна к рублю" (т.к. Sum s1(500, 8.5, "UAH") ). Выкладываю весь код
Кликните здесь для просмотра всего текста
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// <NewEXE> <Задача 11, денежная сумма> <14.03.2014>
 
#include <iostream>
#include <clocale>
#include <string>
#include <tinyxml.h>
using namespace std;
 
class Sum
{
private:
    float sum;
    string code;
    float kurs;
 
public:
 Sum() // Конструктор по-умолчанию
    {
        SetSum(1);
        SetCode("USD");
        SetKurs(1);
    }
 
 Sum(float IntSum, float IntKurs, string IntCode) // Инициализирующий конструктор
    {
        if(IntSum > 0 && IntKurs > 0)
            {
                SetSum(IntSum);
                SetCode(IntCode);
                SetKurs(IntKurs);
            }
        else
            {
                SetSum(1);
                SetCode("USD");
                SetKurs(1);
            }
 }
 
 Sum(Sum& c) // Копирующий конструктор
    {
        SetSum(c.sum);
        SetCode(c.code);
        SetKurs(c.kurs);
    }
 
 Sum(float IntSum, float IntKurs) // К-р преобразования
    {
        SetSum(IntSum);
        SetKurs(IntKurs);
        SetCode("USD");
    }
 
 void Init(float IntSum, float IntKurs, string IntCode) // Функция инициализации
    {
        if(IntSum > 0 && IntKurs > 0)
            {
                SetSum(IntSum);
                SetCode(IntCode);
                SetKurs(IntKurs);
            }
        else
            {
                SetSum(1);
                SetCode("UAH");
                SetKurs(1);
            }
    }
 
 void Print() const // Функция вывода на экран объекта "сумма"
    {
        cout << "Код валюты: \n" << code <<endl << "Кол-во: " << sum <<endl << "Курс доллара: " << kurs <<endl<<endl;
    }
 
 void Print4float(float N) const // Функция вывода на экран числа float
    {
        cout << N <<endl;
    }
 
 void Sravn(Sum s2) const // Сравнение двух сумм
    {
        if(sum > s2.sum)
            cout << "Первая сумма > Второй суммы";
        if(sum < s2.sum)
            cout << "Первая сумма < Второй суммы";
        if(sum == s2.sum)
            cout << "Суммы равны";
    }
 
 float Add(Sum s2) // Сложение двух сумм
    {
        float Rezult;
        Rezult = sum + s2.sum;
        return Rezult;
    }
 
 float Convert() // Вычисление значения суммы в долларах
    {
        float Rezult;
        Rezult = sum / kurs;
        return Rezult;
    }
 
 float GetSum()
    {
        return sum;
    }
 
 string GetCode()
    {
        return code;
    }
 
 float GetKurs()
    {
        return kurs;
    }
 
 void SetSum(float f)
    {
        if(f < 0)
            sum = 1;
        else sum = f;
    }
 
 void SetCode(string s)
    {
        if(s == "")
            code = "USD";
        else code = s;
    }
 
  void SetKurs(float f)
    {
        if(f <= 0)
            kurs = 1;
        else kurs = f;
    }
};
 
int main()
{
    setlocale(0, "");
 
    float any2rur, to_usd_into_rur;
    Sum s1(500, 8.5, "UAH");
 
    TiXmlDocument *xml_MAIN = new TiXmlDocument("XML_daily.asp.xml");
    if(!xml_MAIN->LoadFile())
        return 1;
    TiXmlElement *xml_ValCurs = 0;
    TiXmlElement *xml_Valute = 0;
    TiXmlElement *xml_CharCode = 0;
    TiXmlElement *xml_Name = 0;
    TiXmlElement *xml_Value = 0;
 
    xml_ValCurs = xml_MAIN->FirstChildElement("ValCurs");
    xml_Valute = xml_ValCurs->FirstChildElement("Valute");
    xml_CharCode = xml_Valute->FirstChildElement("CharCode");
    //delete xml_CharCode;
    xml_Name = xml_Valute->FirstChildElement("Name");
    //delete xml_Name;
    xml_Value = xml_Valute->FirstChildElement("Value");
 
    string str1 = xml_CharCode->GetText();
    string str2 = s1.GetCode();
 
    while(xml_Valute != NULL)
    {
         if(str1 != str2) //для этого условия сравнения string
        {
            xml_Valute = xml_Valute->NextSiblingElement("Valute");
        }
        else xml_Value->QueryFloatAttribute("Value", &any2rur);
    }
    cout << &any2rur;
}
0
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
18.05.2014, 01:59 #6
NewEXE, http://www.cplusplus.com/reference/cstring/
0
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
18.05.2014, 02:31  [ТС] #7
outoftime, вы хотите сказать, что я неправильно присваиваю значения string-ам?
C++
1
2
string str1 = xml_CharCode->GetText();
    string str2 = s1.GetCode();

Не по теме:

как благодарить на форуме?

0
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
18.05.2014, 03:05 #8

Не по теме:

Цитата Сообщение от NewEXE Посмотреть сообщение
как благодарить на форуме?
Кнопка "+1 Спасибо" под сообщением



Цитата Сообщение от NewEXE Посмотреть сообщение
вы хотите сказать, что я неправильно присваиваю значения string-ам?
Я хочу сказать что вы вообще не знаете что это такое, поэтому и дал ссылку на описание всех функций для работы с сишными строками (это не строки плюсов, это - си)

Добавлено через 1 минуту
Грубо говоря это просто
C++
1
typedef char* string;
Добавлено через 1 минуту
Ну и договоренность что каждая строка кончается нуль-символом, т.е. значение ячейки массива символов должна быть равна нулю. Почитайте что-то о сишных строках словом..
0
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
18.05.2014, 10:10  [ТС] #9
outoftime, у Вас сложилось ложное впечатление о моих знаниях о std::string. Из char в string легко неявно переводится оператором = (он перегружен для этого). А вот насчет условия - можно было просто сказать, чтобы я попробовал strcmp. Сейчас попробую, отпишусь

C++
1
if(strcmp(str1.c_str(), str2.c_str()) != 0)
не работает, опять то же выводит
1
0x10
2483 / 1658 / 249
Регистрация: 24.11.2012
Сообщений: 4,132
18.05.2014, 10:23 #10
Покажите последний вариант кода и минимальный кусок xml для воспроизведения проблемы.
1
outoftime
║XLR8║
511 / 433 / 33
Регистрация: 25.07.2009
Сообщений: 2,295
18.05.2014, 12:05 #11
Цитата Сообщение от NewEXE Посмотреть сообщение
оператором = (он перегружен для этого)
Не знал. Но тогда лучше использовать copy construct-ор.

Цитата Сообщение от 0x10 Посмотреть сообщение
Покажите последний вариант кода и минимальный кусок xml для воспроизведения проблемы.
Поддерживаю, в библиотечных функциях вряд ли проблема.
1
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
18.05.2014, 19:25  [ТС] #12
Максимально закомментировал main(), чтобы ясны были намерения.

Кликните здесь для просмотра всего текста
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// <NewEXE> <Задача 11, денежная сумма> <14.03.2014>
 
#include <iostream>
#include <clocale> //Для русского в консоли
#include <string>
#include <tinyxml.h>
using namespace std;
 
class Sum
{
private:
    float sum;
    string code;
    float kurs;
 
public:
 Sum() // Конструктор по-умолчанию
    {
        SetSum(1);
        SetCode("USD");
        SetKurs(1);
    }
 
 Sum(float IntSum, float IntKurs, string IntCode) // Инициализирующий конструктор
    {
        if(IntSum > 0 && IntKurs > 0)
            {
                SetSum(IntSum);
                SetCode(IntCode);
                SetKurs(IntKurs);
            }
        else
            {
                SetSum(1);
                SetCode("USD");
                SetKurs(1);
            }
 }
 
 Sum(Sum& c) // Копирующий конструктор
    {
        SetSum(c.sum);
        SetCode(c.code);
        SetKurs(c.kurs);
    }
 
 Sum(float IntSum, float IntKurs) // К-р преобразования
    {
        SetSum(IntSum);
        SetKurs(IntKurs);
        SetCode("USD");
    }
 
 void Init(float IntSum, float IntKurs, string IntCode) // Функция инициализации
    {
        if(IntSum > 0 && IntKurs > 0)
            {
                SetSum(IntSum);
                SetCode(IntCode);
                SetKurs(IntKurs);
            }
        else
            {
                SetSum(1);
                SetCode("UAH");
                SetKurs(1);
            }
    }
 
 void Print() const // Функция вывода на экран объекта "сумма"
    {
        cout << "Код валюты: \n" << code <<endl << "Кол-во: " << sum <<endl << "Курс доллара: " << kurs <<endl<<endl;
    }
 
 void Print4float(float N) const // Функция вывода на экран числа float
    {
        cout << N <<endl;
    }
 
 void Sravn(Sum s2) const // Сравнение двух сумм
    {
        if(sum > s2.sum)
            cout << "Первая сумма > Второй суммы";
        if(sum < s2.sum)
            cout << "Первая сумма < Второй суммы";
        if(sum == s2.sum)
            cout << "Суммы равны";
    }
 
 float Add(Sum s2) // Сложение двух сумм
    {
        float Rezult;
        Rezult = sum + s2.sum;
        return Rezult;
    }
 
 float Convert() // Вычисление значения суммы в долларах
    {
        float Rezult;
        Rezult = sum / kurs;
        return Rezult;
    }
 
 float GetSum()
    {
        return sum;
    }
 
 string GetCode()
    {
        return code;
    }
 
 float GetKurs()
    {
        return kurs;
    }
 
 void SetSum(float f)
    {
        if(f < 0)
            sum = 1;
        else sum = f;
    }
 
 void SetCode(string s)
    {
        if(s == "")
            code = "USD";
        else code = s;
    }
 
  void SetKurs(float f)
    {
        if(f <= 0)
            kurs = 1;
        else kurs = f;
    }
};
 
int main()
{
    setlocale(0, "");
 
    float any2rur, to_usd_into_rur;
    Sum s1(500, 8.5, "UAH"); //кол-во денег, курс к доллару, гривны
 
    TiXmlDocument *xml_MAIN = new TiXmlDocument("XML_daily.asp.xml"); 
    if(!xml_MAIN->LoadFile()) //если произошла ошибка загрузки файла
        return 1;
    TiXmlElement *xml_ValCurs = 0;
    TiXmlElement *xml_Valute = 0;
    TiXmlElement *xml_CharCode = 0;
    TiXmlElement *xml_Name = 0;
    TiXmlElement *xml_Value = 0;
 
/* Такими нехитрыми действиями добираюсь к нужному мне тегу Value нужного CharCode
(в нашем случае, UAH) */
    xml_ValCurs = xml_MAIN->FirstChildElement("ValCurs");
    xml_Valute = xml_ValCurs->FirstChildElement("Valute");
    xml_CharCode = xml_Valute->FirstChildElement("CharCode");
    xml_Name = xml_Valute->FirstChildElement("Name");
    //delete xml_Name; //пока не выяснил, в чем проблема, не буду удалять, во избежание новых
    xml_Value = xml_Valute->FirstChildElement("Value");
 
/* для сравнения CharCode XML-файла и моего s1.code (UAH) */
    string str1 = xml_CharCode->GetText(); //получил CharCode
    string str2 = s1.GetCode(); //получил s1.code
 
    while(xml_Valute != NULL) // проходим по всем полям "Valute" (по примеру из документации)
    {
         if(str1 != str2) //если в CharCode не гривны, то...
        {
            xml_Valute = xml_Valute->NextSiblingElement("Valute"); // идем дальше по полям "Valute"
        }
        else xml_Value->QueryFloatAttribute("Value", &any2rur); //иначе же сохраняем значение "Value" в any2rur
    }
    cout << &any2rur; // тут 0x28fedc. Должно быть 29,2879
    return 0;
}
XML
1
2
3
4
5
6
7
8
9
<ValCurs Date="17.05.2014" name="Foreign Currency Market">
    <Valute ID="R01720">
    <NumCode>980</NumCode>
    <CharCode>UAH</CharCode>
    <Nominal>10</Nominal>
    <Name>Украинских гривен</Name>
    <Value>29,2879</Value>
    </Valute>
<-- Другие Valute -->
http://www.cbr.ru/scripts/xml_daily.asp , сохранен локально


Добавлено через 6 минут

Добавлено через 10 минут

Не по теме:

Потом еще учту информацию поля Nominal, организую функцию присвоения CharCode моему code, функцию перевода рублей в доллары, добавлю деструкторы, класс-контейнер, найду способ вытащить из asp xml (чтоб работало по http), оснащу графическим интерфейсом WinForms, можут быть, что-то придумаю насчет полиморфизма и наследования, запилю инсталлятор. И будет простенький онлайн-оффлайн конвертер валют :-) Но с этим мне помощь не нужна (по крайней мере, пока что)

0
0x10
2483 / 1658 / 249
Регистрация: 24.11.2012
Сообщений: 4,132
18.05.2014, 20:49 #13
NewEXE, в строке 178 выводится адрес переменной. Это явно не то, чего вы ожидаете.
Второй косяк - в строках 167-168 сохраняются значения искомого кода валюты и кода из первого узла. Больше значения нигде не меняются, только xml_Valute бежит по узлам. Естественно, они никогда не станут равны, и присваивание в строке 176 никогда не будет выполнено.
1
NewEXE
4 / 4 / 1
Регистрация: 03.05.2014
Сообщений: 24
18.05.2014, 21:49  [ТС] #14
0x10,
Сделал так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
while(xml_CharCode != NULL)
    {
        if(xml_CharCode->GetText() != str2)
        {
            xml_CharCode = xml_CharCode->NextSiblingElement("CharCode");
        }
        else str1 = xml_CharCode->GetText();
    }
 
while(xml_Valute != NULL)
    {
         if(str1 != str2) //для этого условия сравнения string
        {
            xml_Valute = xml_Valute->NextSiblingElement("Valute");
        }
        else xml_Value->QueryFloatAttribute("Value", &any2rur);
    }
    cout << any2rur;
не работает
0
0x10
2483 / 1658 / 249
Регистрация: 24.11.2012
Сообщений: 4,132
18.05.2014, 21:58 #15
У узла CharCode нет таких же узлов его уровня (siblings).
Используйте отладочную печать на каджом шаге - бысрее разберетесь.
1
18.05.2014, 21:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.05.2014, 21:58
Привет! Вот еще темы с ответами:

Как преобразовать string в char*? - C++
Как преобразовать string в char* и отправить как аргумент наименьшими усилиями? #include &lt;iostream&gt; #include &lt;string&gt; using...

Где и почему используют ту или иную строку std::string, char[], System::String^ ? - C++
Где и почему используют ту или иную строку std::string, char, System::String^ ? Объясните пожалуйста где нужно использовать...

Как преобразовать переменную string в массив char[]? - C++
Есть переменная string и массив char как записать переменную типа string в такой массив ? String X=&quot;test&quot;; char Mass; ...

Как преобразовать объект string в строку char*? - C++
Доброго времени суток! Недавно я писал код, и обнаружил, что в качестве имя файла при объявлении объектов ifstream/ofstream нельзя...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.