Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как извлечь числовое значение из HTML, извлечение данных из HTML  
V
    Опции темы
kresh
Дата 24.3.2008, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 125
Регистрация: 1.1.2008
Где: Минск

Репутация: нет
Всего: нет



Всем привет! Есть вопрос ,как извлечь данные из HTML  файла без применения специальных средств по Xml(т.е препод сказал
что это можно сделать используя только с++). Вот файл из которого надо извлечь данные

Код

CHF<td nowrap>1 швейцарский франк<td align
=right>2 128.76<tr><td align=centrer>


Надо извлечь  число 2128.76 и записать его в переменную. Я делал так

1. Получал  указатель на место в строке где находиться точка, а как дальше считать число двигаясь от этой точки(разделителя) чего то не пойму.
Вот  мой код

Код

#include "stdafx.h"
#include <string>
#include <fstream>
#include <iostream>
#include <cctype>
float kurs;

using namespace std;
void ERASE(char szData[5000])


    ifstream TempBank("TempBank.txt");

    if (!TempBank){cout<<"\n File not open";}
    
    TempBank>>szData[2697];
    cout<<szData;
//преобразуем  С-строку в объект класса string с помощью конструктора(СТАНДАРТНЫЙ КЛАСС)
     
    char AUD[]="CHF";
    char gg[]=".";
    char *pdest;
    char *KURSS;

   //  stszData=szData;
    //for (int i=0;i<2696;i++){
    
        pdest=strstr(szData,AUD);/*поиск подстроки в строке,в 
                                 случае положительного результата
                                  возвращает указатель на элемент из szData*/

        if(pdest!=NULL){cout<<"\n index="<<pdest;
        KURSS=strstr(pdest,gg);
        cout<<"\n ==================================================================================";
        cout<<"\n===="<<KURSS;


Это сообщение отредактировал(а) kresh - 24.3.2008, 11:04
--------------------
Спросит вас продавец в магазине формулу Гаусса-Остроградского... А вы ее не знаете!
PM MAIL   Вверх
Alek86
Дата 24.3.2008, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



1. Я бы препода наколол - использовав бустовский регексп smile (или вообще xml-parser - он же на сях )
2. Не очень понятно задание. Только для этой строки нужно выделить только это число? Если так, то можно найти в строке
Код
CHF<td nowrap>1 швейцарский франк<td align
=right>2 128.76<tr><td align=centrer>

строки
Код
right>

и
Код
<tr>

то, что между ними - и есть число 2 128.76
(или вообще посчитать самому где оно находится и сделать substr


--------------------
user posted image    user posted image
PM MAIL   Вверх
kresh
Дата 24.3.2008, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 125
Регистрация: 1.1.2008
Где: Минск

Репутация: нет
Всего: нет



тАК ПОДСЧИТАТЬ МЕСТО РАСПОЛОЖЕНИЕ ЧИСЛА ЭТО ПРОСТО, А ВОТ СДЕЛАТЬ ТАК ЧТОБ ЧИСЛО ИЗВЛЕКАЛОСЬ НЕ ЗАВАСИМО ОТ ЕГО РАСПОЛОЖЕНИЯ ВОТ ЭТО ВОПРОС!  пРЕПОД ГОВОРИТ ЧТО ТИПА НАДО ИСКАТЬ РАЗДЕЛИТЕЛЬ -ТОЧКУ И ОТ НЕЁ ДВИГАТЬСЯ ДАЛЬШЕ ИСПОЛЬЗУЯ ФУНКЦИИ ДЛЯ ИЗВЛЕЧЕНИЯ ЧИСЛОВЫХ ПОСЛЕДОВАТЕЛЬНОСТЕЙ,ЧТО ОНА ИМЕЛА ВВИДУ ВИГ ЕЁ ЗНАЕТ.
--------------------
Спросит вас продавец в магазине формулу Гаусса-Остроградского... А вы ее не знаете!
PM MAIL   Вверх
Alek86
Дата 24.3.2008, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



В общем если другие не хотят тебе помогать, то я вот налабал (как раз вспомнил работу с stl)
Работает не всегда верно. Коли уж не будет других вариантов, можешь попытаться разобраться smile

Код

#include <iostream>
#include <algorithm>
#include <locale>

bool IsPoint(char i_ch) {
  return i_ch == '.';
}

struct IsIntegralDigit {
  IsIntegralDigit() : m_delimiter(0) {}
  bool operator()(char i_ch) {
    bool res = (i_ch >= '0' && i_ch <= '9');
    if (3 == m_delimiter++) {
      bool is_space = (i_ch == ' ');
      res |= is_space;
      if (is_space)
        m_delimiter = 0;
    }
    return res;
  }
private:
  size_t m_delimiter;
};

int main() {
  std::string str = "wds dasd as12 232 323.456sdfdf";
  std::string::const_iterator it_end = str.end();
  std::string::const_iterator it_beg = str.begin();
  std::string::const_iterator it_point = std::find_if(str.begin(), str.end(), IsPoint);
  std::string::const_iterator it_after = it_point;
  // find digits after point
  if (it_point != it_end)
    for (++it_after; it_after != it_end && isdigit(*it_after); ++it_after);
  // find digits before point
  std::string::const_iterator it_before = it_point;
  IsIntegralDigit is_integral_digit;
  if (it_point != it_beg)
    for (--it_before; it_before != it_beg && is_integral_digit(*it_before); --it_before);
  ++it_before; // now it's on digit or space
  if (*it_before == ' ')
    ++it_before;
  if (it_before != it_after)
    std::copy(it_before, it_after, std::ostream_iterator<char>(std::cout));
}



--------------------
user posted image    user posted image
PM MAIL   Вверх
inside_pointer
Дата 24.3.2008, 13:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Попробуй вот такую ещё
Код

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/* 
 * Выдернуть число 2 128.76
 *
 * 1: CHF<td nowrap>1 швейцарский франк<td align
 * 2: =right>2 128.76<tr><td align=centrer>
 *
 */       

int main()

{
    char str[500] = "CHF<td nowrap>1 швейцарский франк<td align=right>2 128.76<tr><td align=centrer>";
    char chislo[10];
        
    int i, j;
    double n;
    
    for (i = strcspn(str, "."); str[i-1] != '>'; --i)
        ;
    
    for (j = 0; str[i+j] != '<'; ++j) {
        if (str[i+j] == ' ')
            ++i;
        chislo[j] = str[i+j]; 
        chislo[j+1] = '\0';
    }
        
    n = strtod(chislo, NULL);

    printf("%.2f\n", n);

    return 0;
}

//
 

PM MAIL   Вверх
profispb
Дата 24.3.2008, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.12.2005
Где: Санкт - Петербург

Репутация: 1
Всего: 1




Модератор: Сообщение скрыто.

--------------------
В жизни, я люблю делать, то что я люблю. А не то что модно, престижно и выгодноЛюблю когда начинает работать, то что без меня не работало!
PM MAIL ICQ   Вверх
Alek86
Дата 24.3.2008, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



profispb, интересно как ты учтешь пробел каждые 3 символа?


--------------------
user posted image    user posted image
PM MAIL   Вверх
profispb
Дата 24.3.2008, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.12.2005
Где: Санкт - Петербург

Репутация: 1
Всего: 1



Цитата(Alek86 @ 24.3.2008,  14:49)
profispb, интересно как ты учтешь пробел каждые 3 символа?

Я написал примерно, а нафиг в данной задачи их учитывать, если нам надо просто выбрать из текста цифры?

Если надо учитывать, то можно ещё одно условие ввести!)

Это сообщение отредактировал(а) profispb - 24.3.2008, 16:07
--------------------
В жизни, я люблю делать, то что я люблю. А не то что модно, престижно и выгодноЛюблю когда начинает работать, то что без меня не работало!
PM MAIL ICQ   Вверх
Alek86
Дата 24.3.2008, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



1. не ругайся, это не чат
2. посмотри внимательней на представленную строку HTML-кода
3. учитывать легче всего начиная с точки, потому препод был прав


--------------------
user posted image    user posted image
PM MAIL   Вверх
profispb
Дата 24.3.2008, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.12.2005
Где: Санкт - Петербург

Репутация: 1
Всего: 1



Цитата(Alek86 @ 24.3.2008,  16:12)
1. не ругайся, это не чат
2. посмотри внимательней на представленную строку HTML-кода
3. учитывать легче всего начиная с точки, потому препод был прав

1. Я не ругался... а слегка выразился!))
2. Если исходить из пердставленной строки тогда, да.(В принципе вообще в лоб можно решить, но эт не интересно, эт интересно только когда тебе минут через 10 сдавать, а у тебя ещё ничего не написано) !
3. А при универсальности, лучше так как я предложил!)
--------------------
В жизни, я люблю делать, то что я люблю. А не то что модно, престижно и выгодноЛюблю когда начинает работать, то что без меня не работало!
PM MAIL ICQ   Вверх
Alek86
Дата 24.3.2008, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(profispb @  24.3.2008,  16:54 Найти цитируемый пост)
а слегка выразился!

Цитата(profispb @  24.3.2008,  14:45 Найти цитируемый пост)
<censored 8>...


при универсальности нужно регексп для таких задач применять
или вообще xml-парсер


--------------------
user posted image    user posted image
PM MAIL   Вверх
profispb
Дата 24.3.2008, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.12.2005
Где: Санкт - Петербург

Репутация: 1
Всего: 1



Цитата(Alek86 @ 24.3.2008,  16:57)
Цитата(profispb @  24.3.2008,  16:54 Найти цитируемый пост)
а слегка выразился!

Цитата(profispb @  24.3.2008,  14:45 Найти цитируемый пост)
<censored 8>...


при универсальности нужно регексп для таких задач применять
или вообще xml-парсер

Я с тобой соглашусь, но ведь у человека обычная учебная задачка, смысла в xml-парсере нет!)))
--------------------
В жизни, я люблю делать, то что я люблю. А не то что модно, престижно и выгодноЛюблю когда начинает работать, то что без меня не работало!
PM MAIL ICQ   Вверх
kresh
Дата 24.3.2008, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 125
Регистрация: 1.1.2008
Где: Минск

Репутация: нет
Всего: нет



Цитата(profispb @ 24.3.2008,  14:45)
Цитата(kresh @ 24.3.2008,  11:43)
тАК ПОДСЧИТАТЬ МЕСТО РАСПОЛОЖЕНИЕ ЧИСЛА ЭТО ПРОСТО, А ВОТ СДЕЛАТЬ ТАК ЧТОБ ЧИСЛО ИЗВЛЕКАЛОСЬ НЕ ЗАВАСИМО ОТ ЕГО РАСПОЛОЖЕНИЯ ВОТ ЭТО ВОПРОС!  пРЕПОД ГОВОРИТ ЧТО ТИПА НАДО ИСКАТЬ РАЗДЕЛИТЕЛЬ -ТОЧКУ И ОТ НЕЁ ДВИГАТЬСЯ ДАЛЬШЕ ИСПОЛЬЗУЯ ФУНКЦИИ ДЛЯ ИЗВЛЕЧЕНИЯ ЧИСЛОВЫХ ПОСЛЕДОВАТЕЛЬНОСТЕЙ,ЧТО ОНА ИМЕЛА ВВИДУ ВИГ ЕЁ ЗНАЕТ.

Я считаю что препод немного не прав!
Алгоритм решения такой:
1) Создать массив из цифр от 0 до 9
2) Читаем файл посимвольно
3) Далее делаем цикл и проверяем каждый символ.
В цикле надо ещё несколько условий
3.1) Если символ равен одному символу из массива цифр, то проверять следю стоящую и т.д. и заносить в буферную переменную, потом в нужную переменную.
3.2) Если символ равен одному символу из массива цифр, то занести в нужную переменную.
4) Вывести переменную на экран...

<censored 8>... как-то коряво, но суть понятна надеюсь.. просто щас под рукой компилятора нету.... так бы накорябал..)))

Весь прикол в том что данная страничка  с кодом HTML загружается из инета и данное числовое значение 
Код
CHF<td nowrap>1 швейцарский франк<td align
=right>2 128.76<tr><td align=centrer>

постоянно меняется! Народ я все таки непонял как все таки число 2128.76 передать полностью,а не почастям? smile 
--------------------
Спросит вас продавец в магазине формулу Гаусса-Остроградского... А вы ее не знаете!
PM MAIL   Вверх
Alek86
Дата 24.3.2008, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



от точки влево надо искать все цифры, ( + каждый третий символ может быть пробелом). как найдется символ, что ни цифра ни пробел, закончить поиск
а вправо просто цифры.
получишь начало и конец числа


--------------------
user posted image    user posted image
PM MAIL   Вверх
profispb
Дата 24.3.2008, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 27.12.2005
Где: Санкт - Петербург

Репутация: 1
Всего: 1



Цитата(Alek86 @ 24.3.2008,  18:43)
от точки влево надо искать все цифры, ( + каждый третий символ может быть пробелом). как найдется символ, что ни цифра ни пробел, закончить поиск
а вправо просто цифры.
получишь начало и конец числа

Мне даже стало интересно, что ты так к пробелам то привезался, если выбрать только цифры надо?)
--------------------
В жизни, я люблю делать, то что я люблю. А не то что модно, престижно и выгодноЛюблю когда начинает работать, то что без меня не работало!
PM MAIL ICQ   Вверх
inside_pointer
Дата 25.3.2008, 00:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(profispb)

Я написал примерно, а нафиг в данной задачи их учитывать, если нам надо просто выбрать из текста цифры?

Там есть цифры которые не надо, в данном случае одна, а в любом случае их может быть больше, да ещё и с каждой стороны.

Цитата(kresh)

Народ я все таки непонял как все таки число 2128.76 передать полностью

Даже если ты захочешь передать сразу, всё равно у тебя получится тогда два числа из-за пробела 2 и 128.76

Можешь конечно посчитать количество цифр до точки в числе 128.76, а потом умножить первое число 2 на 10 в такой(посчитанной) степени и прибавить 2000 к 128.76, или степень реализовать через цикл с тремя шагами.
PM MAIL   Вверх
kresh
Дата 25.3.2008, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 125
Регистрация: 1.1.2008
Где: Минск

Репутация: нет
Всего: нет



Цитата(inside_pointer @ 25.3.2008,  00:09)

Даже если ты захочешь передать сразу, всё равно у тебя получится тогда два числа из-за пробела 2 и 128.76Можешь конечно посчитать количество цифр до точки в числе 128.76, а потом умножить первое число 2 на 10 в такой(посчитанной) степени и прибавить 2000 к 128.76, или степень реализовать через цикл с тремя шагами.






Спасибо inside_pointer smile   за идею,я её начал развивать, для лучшего чтения числа я решил  преобразовать символьный массив в string и удалить из документа все пробелы.Но вот почему то при выполнение программы в том виде в которым вы писали программа не продвигается дальше точки!Сейчас думаю над этими вопросами!  smile  smile 

Это сообщение отредактировал(а) kresh - 25.3.2008, 10:30
--------------------
Спросит вас продавец в магазине формулу Гаусса-Остроградского... А вы ее не знаете!
PM MAIL   Вверх
inside_pointer
Дата 25.3.2008, 11:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



Цитата(kresh)

Но вот почему то при выполнение программы в том виде в которым вы писали программа не продвигается дальше точки!

Может быть потому что это язык С а не С++, а может быть потому что у меня линукс а не виндовс.
В итоге получается double число слитное.
PM MAIL   Вверх
inside_pointer
Дата 25.3.2008, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 9.3.2008

Репутация: 5
Всего: 12



На винде тоже всё работает.
PM MAIL   Вверх
creatorcode
Дата 26.3.2008, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 12.6.2006
Где: Ленинград

Репутация: нет
Всего: 4



Вот наваял. Вроде работает.  smile
Код

#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
#include <cmath>
void main()
{
    string tmp,s="CHF<td nowrap>1 швейцарский франк<td align=right>2 128.76<tr><td align=centrer>";
    string::const_iterator i=find(s.begin(),s.end(),'.'),j=i;
    for (--i;isdigit(*i) || isspace(*i);--i);
    for (++j;isdigit(*j);++j);
    remove_copy(i+1,j,back_inserter(tmp),' ');
    double result=atof(tmp.c_str());
    cout<<result<<endl;
}


Это сообщение отредактировал(а) creatorcode - 26.3.2008, 00:31
PM MAIL   Вверх
kresh
Дата 26.3.2008, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 125
Регистрация: 1.1.2008
Где: Минск

Репутация: нет
Всего: нет



Спасибо всем друзья за помощь!   smile 
--------------------
Спросит вас продавец в магазине формулу Гаусса-Остроградского... А вы ее не знаете!
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1372 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.