Часть 2. Я начинающий, подскажите как...(Все вопросы начинающих!!!)
ListBox1->Columns=3;
каким образом записать строку в второй и третий столбцы?
Судя по примерам мне требуется путь такого вида: bookstore//book. Но как соединить мой путь (//*[@id= 'news-id-186001']) - тело, с выбором в нем аргумента href ("//a[@href]"). Таких примеров я не нашел. Вариант типа ( *[@id= 'news-id-186001']//"//a[@href]") не проходит.
Во-первых, имена тэгов должны быть в правильном регистре. Если на веб-странице указан тэг html, то XPath "HTML" не совпадёт! Вероятно, поэтому, путь "/HTML/body//a[@href]" ни к чему не приводит.
Атрибут id - уникальный идентификатор. Поэтому нет смысла стремиться получить коллекцию элементов с таким идентификатором. Элемент будет всего один (или ни одного). Но узлов-потомков у него, конечно же, может быть много.
Вот такой код у меня выводит все ссылки внутри элемента (это div) с id=mngb. Тестировал на страничке Гугла.
HtmlAgilityPack.HtmlDocument doc = web.Load("http://www.google.ru");
HtmlNodeCollection nodes = doc.DocumentNode
.SelectNodes("//*[@id='mngb']//a[@href]");
if (nodes == null)
return;
foreach (HtmlNode node in nodes)
{
listBox1.Items.Add(node.Attributes["href"].Value);
}
Такой путь: *[@id= 'news-id-186001']//"//a[@href] вероятно должен выглядеть так: *[@id= 'news-id-186001']//a[@href]
Лучше, конечно, указывать более определённый путь. Скажем, в моём коде, лучше задать "//div[@id='mngb']//a[@href]" - то есть div вместо звёздочки.
Ещё лучше "html/body//div[@id='mngb']//a[@href]" - тогда не будет зря проверяться заголовок head на веб-странице.
P.S. советы rikki не слушай ;)
Сколько об этом уже говорено! Не надо парсить html регулярками! Это не регулярная грамматика! Попадутся в атрибутах, в комментариях или в javascript'е совпадающие строки - и всё, найдётся не то.
Вручную, с помощью строковых фукнций, тоже не стоит этого делать. Это не производительно, получается много кода.
И регулярки, и строковые функции можно применять, но лишь в редких случаях.
Хотя за попытку помочь, конечно, молодец.
rikki большое спасибо за реагирование на просьбу. Но в этом случае koodeer абсолютно прав, посмотри на конечный код - маленький и абсолютно понятный, твоя версия была бы на много тяжелее.Присмотрись может и тебе пригодится.
koodeer Огромное спасибо за реальную помощь. Как я и думал моя ошибка в xpath.
Ниже публикую свой рабочий код, думаю это будет полезно для форума.
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Web;
using HtmlAgilityPack;
namespace Keys1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
HtmlWeb web = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = web.Load("URL сайта");
HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("html/body//div[@id= 'news-id-186001']//a[@href]");
if (nodes == null)
return;
foreach (HtmlNode node in nodes)
{
listBox1.Items.Add(node.Attributes["href"].Value);
}
}
}
}
Этот вопрос можно считать закрытым.:)
pop(top) в первом цикле в функции delNegative возвращает нуль. Черт, почему?
#include <stdlib.h>
struct Node{
int d;
Node *p;
};
Node *first(int d);
void push(Node **top,int d);
int pop(Node **top);
void delNegative(Node **top);
int main(){
int tmp;
Node *top;
for(int i=0;i<5;i++){
cout << "Enter "<<i+1<<"-th element: ";
cin >> tmp;
if(i==0) top = first(tmp);
else push(&top,tmp);
}
delNegative(&top);
while(top) cout << pop(&top)<< " ";
cout <<endl;
system("pause");
return 0;
}
void delNegative(Node **top){
Node *temp;
int i=0,tmp;
while(top){
tmp = pop(top);
if(tmp >= 0){
if(i == 0){
temp = first(tmp);
i++;
}else{
push(&temp,tmp);
}
}
}
i=0;
while(temp){
if(i != 0){
push(top,pop(&temp));
}else{
*top = first(pop(&temp));
i++;
}
}
}
Node *first(int d){
Node *pv = new Node;
pv->d = d;
pv->p = 0;
return pv;
}
void push(Node **top,int d){
Node *pv = new Node;
pv->d = d;
pv->p = *top;
*top = pv;
}
int pop(Node **top){
int temp = (*top)->d;
Node *pv = *top;
*top = (*top)->p;
delete pv;
return temp;
}
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Page);
return doc.DocumentNode.InnerText;
}
возвращает кучу стороннего хлама, даже теги ссылок, хотя на забугорных форумах вроде все хвалят. Что я делаю не так, и как снести без исключения теги? Раньше писал именно регулярками.(можно не объяснять почему это плохо - уже понял))
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Page);
return doc.DocumentNode.InnerText;
}
возвращает кучу стороннего хлама, даже теги ссылок, хотя на забугорных форумах вроде все хвалят. Что я делаю не так, и как снести без исключения теги? Раньше писал именно регулярками.(можно не объяснять почему это плохо - уже понял))
По моему ты в своем примере HtmlAgilityPack еще не используешь. скачай саму библиотеку HtmlAgilityPack.dll, закинь ее в папку bin проекта. Потом подключи ее через Projct/Add Reference и пропиши в using: using HtmlAgilityPack;
а твои строки должны быть типа:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(Page);
Ну, а дальше извини, саму работу библиотеки подскажут более знающие.
Ну и ладушки, просто в том коде что ты показал, по моему, ты загрузил страницу в doc и сразу же вывел ее, самого по себе парсинга ты не сделал.
Забыл - по ссылке вышеупомянутые умные люди подсказали как убрать теги скриптов и стилей.
Апдейт:
Проблема решена, метод оставляет только текст без тегов и прочего, правда с кучей пробелов:
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(Page);
foreach (var script in doc.DocumentNode.Descendants("script").ToArray())
script.Remove();
foreach (var style in doc.DocumentNode.Descendants("style").ToArray())
style.Remove();
var nodes = doc.DocumentNode.SelectNodes("//comment()");
if (nodes != null)
{
foreach (HtmlNode comment in nodes)
{
comment.ParentNode.RemoveChild(comment);
}
}
return doc.DocumentNode.InnerText;
}
Может кому пригодиться.
RichTextBox занимает на экране одну и ту же площадь внутри одной формы с pictureBox и groupBox и по замыслу должен по следующим командам
this.myBox.Visible = true;
this.myBox.BringToFront();
накрывать pictureBox и groupBox. Реально, закрывается только pictureBox но прячется под groupBox и текстовое окошко видно не полностью.
как поместить RichTextBox на передний план?
RichTextBox занимает на экране одну и ту же площадь внутри одной формы с pictureBox и groupBox и по замыслу должен по следующим командам
this.myBox.Visible = true;
this.myBox.BringToFront();
накрывать pictureBox и groupBox. Реально, закрывается только pictureBox но прячется под groupBox и текстовое окошко видно не полностью.
как поместить RichTextBox на передний план?
groupBox.SendToBack();
Если не поможет у формы попробуй вызвать UpdateZOrder();
Если текстовую форму вытянуть достаточно далеко от pictureBox, примерно чтоб % 60 было вне этой площади, она появляется.
Глюк?
Дизайнер походу устанавливает парентом picturebox для richtextbox'а.
Попробуй myBox.Parent=this;
{
class Second
{
T* arg;
Second(T* a) : arg(a){}
public:
Func(arg);
};
static void Func(T* arg)
{
//имплементация функции
}
};
Пишет:
error: declaration of 'class T'
error: shadows template parm 'class T'
Как сделать, чтобы Second брал T класса First?
UPD: всё это делается на Qt и методом тыка было выяснено, что в этом повинен макрос Q_OBJECT. Что делать?
#include <stdio.h>
#include <conio.h>
#include <fstream>
#include <string>
#include <cstring>
#include <set>
#define N 208459
#define M 3
using namespace std;
int main(int argc, char* argv[])
{
fstream plik;
plik.open("bunny.dat", ios::in);
double tab[M][N];
int j=0;
int p=0;
double f1, f2, f3, at1, at2, at3, vx, vy, vz, a, w, h, r1, r2, g1, g2, b1, b2, l1, l2, l3, an;
if (!plik)
{
cout<<"Blad";
cin>>p;
return 1;
}
int i=0;
while ( (!plik.eof()) && (p != 5) )
{
char zp[10];
plik>>zp;
if (strcmp (zp, "from") == 0){
plik>>f1;
plik>>f2;
plik>>f3;
}
else if (strcmp (zp, "at") == 0) {
plik>>at1;
plik>>at2;
plik>>at3;
}
else if (strcmp (zp, "up") == 0){
plik>>vx;
plik>>vy;
plik>>vz;
}
else if (strcmp (zp, "hither") == 0) {
plik>>a;
}
else if (strcmp (zp, "resolution") == 0) {
plik>>w;
plik>>h;
}
else if (strcmp (zp, "b") == 0){
plik>>r1;
plik>>g1;
plik>>b1;
}
else if (strcmp (zp, "l") == 0) {
plik>>l1;
plik>>l2;
plik>>l3;
plik>>r2;
plik>>g2;
plik>>b2;
}
else if (strcmp (zp, "p") == 0) {
plik>>p;
plik>>tab[0][j];
plik>>tab[1][j];
plik>>tab[2][j];
j++;
plik>>tab[0][j];
plik>>tab[1][j];
plik>>tab[2][j];
j++;
plik>>tab[0][j];
plik>>tab[1][j];
plik>>tab[2][j];
j++;
}
else if (strcmp (zp, "angle") == 0) {
plik>>an;
}
else if (strcmp (zp, "v") == 0) {
p=0;
}
else{
p=5;
cout << "To juz koniec" << endl;
}
}
for(j=0;j<6;j++) {
for(i=0;i<3;i++) {
cout << "_" << tab[j] << "_ " <<endl;
}
}
cin>>p;
plik.close();
return 0;
}
from 0.1 0.1 0.25
at -0.01 0.085 0.02
up 0 1 0
angle 50
hither 1
resolution 1024 1024
b 0.0 0.0 0.0
l 0.4 0.3 0.2 0.25 0.25 0.25
f 0.753 0.753 0.753 1 0 0 0 1
p 3
-0.092314 0.132364 0.018222
-0.092180 0.132348 0.017224
-0.092767 0.130992 0.017231
p 3
-0.087168 0.110390 0.018362
-0.088961 0.111861 0.018336
-0.087443 0.110454 0.017341
p 3
-0.087840 0.105023 0.014367
-0.087237 0.106355 0.014359
-0.087251 0.106353 0.013364
p 3
-0.087845 0.105020 0.013370
-0.087840 0.105023 0.014367
-0.087251 0.106353 0.013364
p 3
-0.031635 0.051114 -0.013365
-0.032139 0.051169 -0.012424
-0.031901 0.052553 -0.012456
p 3
-0.088668 0.141939 0.012197
-0.089282 0.141954 0.013243
-0.088758 0.143311 0.012150
p 3
-0.034877 0.105695 -0.020446
-0.034878 0.107130 -0.020218
-0.033876 0.105703 -0.020566
p 3
-0.032832 0.092968 -0.024079
-0.033831 0.092955 -0.023961
-0.032841 0.094393 -0.023854
p 3
-0.086041 0.109124 0.010359
-0.085963 0.109007 0.009354
-0.086182 0.107654 0.009363
p 3
-0.086782 0.106320 0.010369
-0.086650 0.106304 0.009372
-0.087232 0.104968 0.009384
p 3
-0.086966 0.148754 0.008249
-0.086153 0.148758 0.007210
-0.086166 0.147397 0.007214
p 3
-0.087201 0.147399 0.008260
-0.086966 0.148754 0.008249
-0.086166 0.147397 0.007214
p 3
-0.017438 0.127681 0.004693
-0.016194 0.128088 0.005150
-0.015763 0.127990 0.003857
p 3
-0.014447 0.128429 0.004348
-0.014935 0.127911 0.002622
-0.015763 0.127990 0.003857
p 3
-0.017868 0.127784 0.005984
-0.016555 0.128252 0.006465
-0.016194 0.128088 0.005150
p 3
-0.013325 0.129244 0.009097
-0.013866 0.129156 0.010348
-0.012604 0.129510 0.010805
p 3
-0.017438 0.127681 0.004693
-0.017868 0.127784 0.005984
-0.016194 0.128088 0.005150
p 3
-0.014348 0.129147 0.011615
-0.014822 0.129108 0.012888
-0.013627 0.129395 0.013324
p 3
-0.012131 0.129539 0.009535
-0.013325 0.129244 0.009097
-0.012604 0.129510 0.010805
p 3
-0.011653 0.129557 0.008268
-0.012851 0.129269 0.007828
-0.012131 0.129539 0.009535
p 3
-0.013019 0.129549 0.012096
-0.014348 0.129147 0.011615
-0.013627 0.129395 0.013324
p 3
-0.017868 0.127784 0.005984
-0.018356 0.127798 0.007257
-0.017104 0.128182 0.007715
p 3
-0.012851 0.129269 0.007828
-0.011653 0.129557 0.008268
-0.011171 0.129564 0.007002
p 3
-0.016555 0.128252 0.006465
-0.017868 0.127784 0.005984
-0.017104 0.128182 0.007715
У нас, у программистов, нет такого понятия "не работает".
Есть понятия: не компилируется (с указанием ошибки, выдаваемой компилятором), не линкуется, выдаёт исключение в рантайме (с указанием исключения и стектрейсом), и прочее.
Итого, вопрос: в чём проблема-то?
#define M 3
...
double tab[M][N];
sizeof(double) = 8.
8 * 3 * 208459 = дофига...
Жирные нонче кролики пошли :).
ppWiaDevMgr=(IWiaDevMgr **) CoTaskMemAlloc(1 * sizeof(IWiaDevMgr *));
HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)ppWiaDevMgr);
pWiaDevMgr=*ppWiaDevMgr;
IEnumWIA_DEV_INFO * pWiaEnumDevInfo = NULL;
hr = pWiaDevMgr->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo );
IWiaPropertyStorage *pWiaPropertyStorage = NULL;
hr = pWiaEnumDevInfo->Next( 1, &pWiaPropertyStorage, NULL );//получаем указатель на интерфейс
PROPSPEC PropSpec[3] = {0};
PROPVARIANT PropVar[3] = {0};
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = WIA_DIP_DEV_ID;
PropSpec[1].ulKind = PRSPEC_PROPID;
PropSpec[1].propid = WIA_DIP_DEV_NAME;
PropSpec[2].ulKind = PRSPEC_PROPID;
PropSpec[2].propid = WIA_DIP_DEV_DESC;
const ULONG c_nPropertyCount = sizeof(PropSpec)/sizeof(PropSpec[0]);
hr = pWiaPropertyStorage->ReadMultiple( c_nPropertyCount, PropSpec, PropVar );
//создание устройства
IWiaItem **ppWiaItem=(IWiaItem **) CoTaskMemAlloc(1 * sizeof(IWiaItem *));
BSTR bstrDeviceID=PropVar[0].bstrVal;//получаем ID устройства
hr = pWiaDevMgr->CreateDevice( bstrDeviceID, ppWiaItem );
IWiaPropertyStorage *pWiaPropertyStorage1 = NULL;
IWiaItem *pWiaItem=*ppWiaItem;
hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage1 );
PROPSPEC PropSpec1[2] = {0};
PROPVARIANT PropVariant1[2] = {0};
const ULONG c_nPropCount = sizeof(PropVariant1)/sizeof(PropVariant1[0]);
GUID guidOutputFormat = WiaImgFmt_BMP;
PropSpec1[0].ulKind = PRSPEC_PROPID;
PropSpec1[0].propid = WIA_IPA_FORMAT;
PropSpec1[1].ulKind = PRSPEC_PROPID;
PropSpec1[1].propid = WIA_IPA_TYMED;
PropVariant1[0].vt = VT_CLSID;
PropVariant1[0].puuid = &guidOutputFormat;
PropVariant1[1].vt = VT_I4;
PropVariant1[1].lVal = TYMED_FILE;
hr = pWiaPropertyStorage1->WriteMultiple( c_nPropCount, PropSpec1, PropVariant1, WIA_IPA_FIRST );//возвращает S_FALSE
Есть программа с 9 нитями. В каждой нити выполняется одна и так же функция. В функции критический ресурс ( в данном случае экран) организован с помощью Interlocked функций. Все работает нормально, но если внутри критической секции поставить Sleep(20); и выше, то появляется загрузка процессора 100%. Если убрать Sleep(20), то загрузка становится нормальной, то есть программа с 9 нитями занимает 0-3% процессорного времени.
Код функции:
// ожидаем доступа к ресурсу
while (1) {
while(InterlockedExchange(&Status,1) == 1)
Sleep(0);
// Получаем монопольный доступ
printf ("Thread is - %d", lpParameter);
printf ("\n");
Sleep(20);
// Уступаем доступ
InterlockedExchange(&Status, 0);
Sleep(100);
}
// Конец критической секции
return 0;
};
Возникает вопрос. Почему такая дикая загрузка проца? Это как то связано с тем, что в windows несерверных квант времени у процессора 20мс. В Рихтере что т ничего не нашел.
И да
printf ("\n");
заменить на
Получается, что ставя Sleep() внутри критической секции, я даю процессору квант лишнего времени, а находясь внутри критической секции, он не может запустить на обработку другие нити, так как им тоже нужны данные, которые в критической секции. Так? Почему загрузка такая?
А покороче запись?
qULL qullV1,qullV2,qullV3,…
qULL qullV1,qullV2,qullV3,…
Так и я умею. Но есть же стандартные дефайны, зачем велосипед?
#include <string>
#include <iomanip>
#include <ios>
#include <stdexcept>
#include <windows.h>
#include <vector>
#include <algorithm>
using namespace::std;
int main ()
{
cout << "Пожалуйста, введите имена студентов: ";
string name;
vector<string> students;
vector<double> ocenka;
while(cin >> name)
students.push_back(name);
cout << "Здравствуйте, уважаемые ";
for(size_t i=0; i < students.size(); ++i)
cout << students[i] << " ";
cout << endl << endl;
for(size_t i=0; i < students.size(); ++i)
{
cout << "Пожалуйста, введите оценки по экзаменам, проведённым в середине и в конце семестра студента " << students[i] << ":";
double midterm, fin;
cin >> midterm >> fin;
cout << "Введите все оценки за выполнение домашних заданий студента " << students[i] << ", завершив ввод признаком конца файла: ";
vector<double> homework;
double x;
while(cin >> x)
homework.push_back(x);
typedef vector<double>::size_type vec_sz;
vec_sz size=homework.size();
if(size == 0)
{
cout << endl << "Необходимо ввести оценки для расчёта. "
"Пожалуйста, попытайтесь снова." << endl;
return 1;
}
sort(homework.begin(), homework.end());
vec_sz mid = size/2;
double median;
median = size % 2 == 0 ? (homework[mid] + homework[mid - 1]) / 2 : homework[mid];
streamsize prec = cout.precision();
cout << "Итоговая оценка за экзамен студента " << students[i] << setprecision(3) << 0.2 * midterm + 0.4 * fin + 0.4 * median << setprecision(prec) << endl;
}
return 0;
}
Можно и так. Но мне нужно только однократное считывание. И оно работает в других случаях. Просто конкретно в этом коде что-то не так.
Этот же код работает:
using namespace std;
int main()
{
double mid, fin;
cin >> mid >> fin;
return 0;
}
В данный момент интересует дескриптор окна в виде IntPtr, возращенный WinAPI'шной функцией. Логика подсказывает, что это всего лишь номер, и делать с ней ничего не нужно. С другой стороны, кто его знает - как эта цифра ко мне попала. Может, ее добавили в какой-нибудь тайный регистр и будет она жить в нем вечно, пока не умрет процесс. Подскажите. :) Буду благодарен за ссылку на какую-нибудь статью по теме. Также интересуют безопасные указатели и случаи, когда их нужно применять.
2) Существует ли корректный способ парсить числа с плавающей точкопятой? Задача тривиальна - "177.4" и "177,4" должны распарситься, как 177.4 в системе с любой локалью и разделителем. Единственный найденный мною способ - объявить формат, н.п. с точкой, после чего все запятые в строке заменить на точку.
Сразу замечу, что тема была как следует обгуглена и на наших и на забугорных сайтах. Поиск результатов не дал. Но попрошу перед любым ответом на этот вопрос проверить свой способ на работоспособность! InvariantCulture не поможет! Канадская локаль не поможет! Исключение разделителей разрядов не поможет! В результате всех виденных мною способов, парсинг одного из чисел либо выдаст исключение, либо одно станет 177.4, а другое - 1774.
Заранее благодарю за любую помощь3rn.ru
Коректный способ парсить числа существует - для этого необходимо получить региональные настройки и пользоваться ими. Например:
GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_SDECIMAL,Buf,2);
FDecimalSeparator = *Buf;
По первому пункту - безопасные указатели надо применять всегда, когда это возможно. Нужно ли их применять в случае описаном автором - я лично хз. Думаю что автору необходимо взять хотябы одну книжку по С++ и прочесть ее, может тогда не будет возникать чушь в голове о тайных реестрах.
В данный момент интересует дескриптор окна в виде IntPtr, возращенный WinAPI'шной функцией
Зависит от типа указателя. В данном случае — нет, но я хотел бы взглянуть на код, который это делает.