مشکل:برررسی لینک های موجود در یک فایل

mhabat

Member
با سلام. وتشکر از thr_kingعزیز.

می خوام برنامه یی بنویسم که یک فایل متنی رو از کاربر بگیره و بعدش تو اون فایل لینک های موجود رو در بیاره و در یک فایل دیگر ذخیره کنه.

نیازی به نوشتن برنامه نیست چون می خوام خودم بنویسم اما می خوام راهنمایی کنید.

طرز کار:

می خوام با تایع cin.getبتونم رشته هارو بررسی کنم به این شکل کارکتر هارو در هر خط چک کنه و اگر به

httpرسید تمام کارکتر های قبل از اون رو پاک کنه . بعد از httpکارکتر هارو بگیره تا قبل از کارکتر " .

سپس از کارکتر " تا وقتی که به httpبعدی میرسه همه ی کار کتر هارو پاک کنه.

حالا برای این کار نمی دونم چطور انجام بدم.

مثلا برای اینکه با استفاده از تابع getفایل مورد نظر رو چک کنم باید چه کار کنم؟

چطوری اون کارکتر هایی که می خوام رو پاک کنم؟

چطوری بعد از این که یک لینک رو پیدا کرد لینک بعدی رو زیر لینک قبلی قرار بده.

ممنون میشم راهنمایی کنید

مرسی
 

mhabat

Member
برای مثال. این سورس رو ببینید:
کد:
cin.getline(clause, 20, ',');
if (*clause) cout << "\t[" << clause << "]\n";
} while (*clause);
}
می خوام به جای clauseاون فایل مورد نظر رو چک کنه باید چی کار کنم؟

یا چی کار کنم که از httpشروع کنه؟

بخوام کارکتر های مورد نظر رو پاک کنم چطور؟

مرسی
 

the_king

مدیرکل انجمن
قرار نیست چیزی رو پاک کنید.

1) یک سطر از فایل را در رشته s بخوانید مگر اینکه به آخر فایل رسیده باشید و تمام.
2) اشاره گر p را روی ابتدای رشته s تنظیم کنید.
3) در p دنبال رشته "http" بگردید. (تابع strstr در string.h یا cstring.h است)
4) اگر پیدا نشد به مرحله 1 بروید.
5) در p + 5 به دنبال رشته " بگردید.
6) از موقعیت شروع http تا موقعیت " مشخص است، هر کاری که خواستید باهاشون بکنید.
7) p را روی موقعیت " تنظیم کنید تا ادامه جستجو بعدی از آنجا باشد.
8) به مرحله 3 بازگردید.
 

mhabat

Member
سلام.خیلی ممنون بابت الگوریتم.
برای این که cin.getlineخط اول از فایل رو بخونه چه کار باید بکنم؟
من کتاب برنامه نویسی پیشرفته رو می خوانم و در مورد فایل ها دربارهی خواندن یک سطر از فایل چیزی نگفته.
چرا pرو با اضافه 5 بکنیم؟
مرسی
 

the_king

مدیرکل انجمن
سلام.خیلی ممنون بابت الگوریتم.
برای این که cin.getlineخط اول از فایل رو بخونه چه کار باید بکنم؟
من کتاب برنامه نویسی پیشرفته رو می خوانم و در مورد فایل ها دربارهی خواندن یک سطر از فایل چیزی نگفته.
چرا pرو با اضافه 5 بکنیم؟
مرسی

برای خواندن یک سطر از فایل از cin استفاده نمی کنید، cin ورودی استاندارد صفحه کلیده. شما باید یک ifstream
اختصاصی برای اون فایل ایجاد کنید که ساختارش خیلی شبیه به cin است، اما اسم اش متغیری است که شما
تعیین می کنید.

رجوع شود به :
نحوه استفاده از فایل در c++

دقیقا مهم نیست که با 5 شروع کنید یا 4 اما طبیعتا اگر در رشته بعد از p عبارت http وجود داشته باشد لزومی ندارد
که جستجو را از حرف h شروع کنید، چون قطعا هیچکدام از کاراکتر های http کاراکتر " نیستند.
 

mhabat

Member
مگه ما نمی خوایم یک سطر رو داخل متغیر sبریزیم؟پس چطور کاری کنیم تا آخر سطر رو چک کنه.
منظورم اینهکه مقداری که به sمیدیم چه قدر باید باشه؟
مثال:
کد:
f.getline(s, 100);

این قسمت رو متجه نمیشم:
مگر اینکه به آخر فایل رسیده باشید و تمام.
ماداریم مقدار یک سطر رو در sمیریزیم (داریم مقدار دهی می کنیم) حالا چطور میتونیم آخر فایل رو چک کنیم؟
 

the_king

مدیرکل انجمن
مگه ما نمی خوایم یک سطر رو داخل متغیر sبریزیم؟پس چطور کاری کنیم تا آخر سطر رو چک کنه.
منظورم اینهکه مقداری که به sمیدیم چه قدر باید باشه؟
مثال:
کد:
f.getline(s, 100);
getline تا آخر سطر رو می خونه، شما فقط باید برای s یک طول حداکثر در نظر بگیرید که به getline اعلام می کنید
(رشته ها طول نامحدود ندارند) 100 یا 1000 یا هر طول حداکثر دیگری، طولی برای s در نظر می گیرید که هیچ
سطری از آن بلند تر نباشد.

این قسمت رو متجه نمیشم:
مگر اینکه به آخر فایل رسیده باشید و تمام.
ماداریم مقدار یک سطر رو در sمیریزیم (داریم مقدار دهی می کنیم) حالا چطور میتونیم آخر فایل رو چک کنیم؟
وقتی به انتهای فایل می رسید ()eof مقدار غیر صفر بر می گرداند (true)، برای همین معمولا خواندن سطر های
پیاپی رو در یک حلقه while قرار می دهند، f مثلا اسم شیء ای است که فایل را با آن می خوانید :
کد:
char s[1000];
while (!f.eof())
{
	f.getline(s, 1000);
	.
	.
	.
}
 

mhabat

Member
سلام.ممنون بابت توضیحات(خیلی خوب توضیح میدین)
سورس رو نوشتم اما مشکل داره.
سورس:
کد:
#include <iostream.h>
#include <conio.h>
#include <fstream.h>
int main() {
 cout << "Please enter file name (For example C:\\TEXT.TXT) : ";
 char filename[100], s[100];
 ifstream f(filename);
 char *p=s;
 char *q=s;
 while (!f.eof())
 {
 f.getline(s, 1000);
        inja:
 p = strstr(s, "http");
        if(p==null)
        continue;
        q=strstr(p+5,'"');
 ifstream link(link.txt);
 for(i=p;s[i] && i<q;i++)
 link << s[i] ; 
        link<<end;
        p=q;
        goto inja;
 }
 getch();
 return 0;
 }
فقط بگین کجا هاشو باید درست کنم خودم درست می کنم.
خیلی ممنون.
 

the_king

مدیرکل انجمن
سلام.ممنون بابت توضیحات(خیلی خوب توضیح میدین)
سورس رو نوشتم اما مشکل داره.
فقط بگین کجا هاشو باید درست کنم خودم درست می کنم.
خیلی ممنون.
1) هیچ مقداری در متغیر filename نریختید، مقدار نداده ازش استفاده کردید.
2) فایل link.txt یک فایل خروجی است، فایل خروجی رو از نوع ifstream ایجاد نمی کنند، ifstream مخصوص
خواندن است، نه نوشتن.
3) اسم و مسیر فایل را بصورت رشته بین دو " قرار دهید.
4) متغیر p و s اشاره گر به کاراکتر هستند، نه اندیس کاراکتر. اگر می خواهید به کاراکتر مورد نظر دسترسی
داشته باشید i را هم از نوع *char تعریف کنید و بجای [s[i از i* استفاده کنید، i* یعنی کاراکتری که i به آن
اشاره می کند. p و q مستقل از s هستند، خودشان به تنهایی موقعیت کاراکتر را مشخص می کنند.
5) فایلی را که باز می کنید با close ببندید، فایل link.txt را هم ابتدای کد باز کنید، نه در وسط حلقه.
وقتی یکبار باز اش کردید دیگر مجددا باز کردنش بی مورد است.
6) به link مقدار endl را ارسال کنید، نه end
 

mhabat

Member
سلام.خیلی ممنون.
1)درست شد.
2)بله من اشتباه کردم به جای ofstreamاز ifstreamاستفاده کردم.
3)این طور کردمش:
کد:
ifstream f("c:\TC\index.txt");
4)این طور میشه؟:
کد:
for(char *i=p;*i && i<q;i++)
5)یادم رفت ببندمش(ببخشید) یه لحظه افتاد یادم که چند بار ممکنه باز بشه اما یادم رفت بیرون از حلقه قرارش بدم.
6)تو endlشک داشتم که این کاری که می کنم باعث میشه که هر لینک در یک خط قرار بگیره با نه(پس درسته)

این قسمت:p و q مستقل از s هستند، خودشان به تنهایی موقعیت کاراکتر را مشخص می کنند
فقط توضیحه؟چیزی نمی خواد تغییر بدم؟

موقع کامپایل ارور میده که نمیشه intرو به charتبدیل کرد مجبور شدم به این شکل بنویسم:
کد:
p = (*char)strstr(s, "http");
q=(*char)strstr(p+5,'"');
درسته؟
فایل کتاب خانه یی stringهم اضافه نکرده بودم.
حالا دو ارور میده:experesion syntac
سورس:
کد:
#include <iostream.h>
#include <conio.h>
#include <fstream.h>
#include <string.h>
int main() {
 char s[1000];
 ifstream f("c:\TC\index.txt");
 char *p=s;
 char *q=s;
 ofstream link("link.txt");
 while (!f.eof())
 {
 f.getline(s, 1000);
        here:
 p = (*char)strstr(s, "http");
        if(p=='\0')
        continue;
        q=(*char)strstr(p+5,'"');
 for(char *i=p;*i && i<q;i++)
 link << *i ; 
        link<<endl;
        p=q;
        goto here;
 }
 link.close();
 getch();
 return 0;
 }
درضمن کلمه nullرو هم نمیشناخت مجبور شدم '\0'بزارم مشکلی نیست؟
خیلی ممنون
 

the_king

مدیرکل انجمن
1) در زبان های C و ++C کاراکتر \ اگر به تنهایی نوشته بشه کد کنترلی است و با کاراکتر بعدی تفسیر میشه،
اگر منظورتان کاراکتر \ است، جفت کاراکتر \\ را بنویسید، مثلا "C:\\TC\\index.txt"
2) getline را درست اجرا نمی کنید، اگر پارامتر اول همیشه s باشه که همیشه اولین مورد http رو پیدا می کنه
و سراغ موارد بعدی نمیره، قرار بود از p استفاده کنید.
3) برای جستجوی رشته " بجای خود کاراکتر " از "\ استفاده میشه، یعنی رشته ""\"
4) در حلقه for نیازی به بررسی null نبودن i* نیست، چون قبل از کاراکتر " که نمی تواند کاراکتر null ای باشد، همان
شرط i < q به تنهایی کافی است.
5) عبارت (*char) با (char*) خیلی فرق دارد، ستاره باید بعد از نوع داده قرار بگیرد تا معنی اشاره گر داشته باشد،
نه قبل از نوع داده.

کد:
#include <iostream.h>
#include <conio.h>
#include <fstream.h>
#include <string.h>

int main()
{
    char s[1000];
    ifstream f("c:\\TC\\index.txt");
    char *p = s;
    char *q = s;
    ofstream link("C:\\TC\\link.txt");
    while (!f.eof())
    {
        f.getline(s, 1000);
        p = s;
        here:
        p = strstr(p, "http");
        if (p == '\0')
            continue;
        q = strstr(p + 5, "\"");
        for (char *i = p; i < q; i++)
            link << *i;
        link << endl;
        p = q;
        goto here;
    }
    link.close();
    getch();
    return 0;
}
 

mhabat

Member
سلام.

ببخشیبد که این تایپک رو بالا آوردم(زیر خاکی که نیست!ماله تازگیاس)

اگه بخوایم به جایه مسیر فایل لینک یک فایل رو به برنامه بدیم باید چه کار کنیم.

باید سوکت نویسی کنیم یا بدونه اون هم میشه.

همچنین اگه به جای فرمت.txtاز فرمت htmlبخوایم استفاده کنیم باید چه کار کنیم.

در کل دو کار بالا به توابعapiو سوکت نویسی ربطی نداره؟

خیلی ممنون

بدرود
 

the_king

مدیرکل انجمن
سلام.

ببخشیبد که این تایپک رو بالا آوردم(زیر خاکی که نیست!ماله تازگیاس)

اگه بخوایم به جایه مسیر فایل لینک یک فایل رو به برنامه بدیم باید چه کار کنیم.

باید سوکت نویسی کنیم یا بدونه اون هم میشه.

همچنین اگه به جای فرمت.txtاز فرمت htmlبخوایم استفاده کنیم باید چه کار کنیم.

در کل دو کار بالا به توابعapiو سوکت نویسی ربطی نداره؟

خیلی ممنون

بدرود

این توابع برای سیستم فایل طراحی شده اند، نه لینک های اینترنتی، باید فایل html رو اول داونلود کنید و بعد
با پردازش رشته سطر هایش را تفکیک کنید.

سوکت ارتباطی با لینک فایل نداره، سوکت صرفا یک داده ای رو از یک IP به یک IP دیگه در شبکه ارسال می کنه،
شیوه کار اش ابتدایی تر از آن است که بخواهید صفحات HTML و آدرس فایل رو بهش ارتباط دهید.
 

mhabat

Member
سلام.مرسی از پاسختون.
اصلا اگه بخوایم اون لینک رو جدا از اینترنت سیو کنه چی؟
مثلا لینک به برنامه بدی بعد خودش سیو کنه و بعد با برنامه بالا تکفیفشون کنه.
این طور هم نمیشه؟
 

the_king

مدیرکل انجمن
سلام.مرسی از پاسختون.
اصلا اگه بخوایم اون لینک رو جدا از اینترنت سیو کنه چی؟
مثلا لینک به برنامه بدی بعد خودش سیو کنه و بعد با برنامه بالا تکفیفشون کنه.
این طور هم نمیشه؟

بله، اگر برای ویندوز برنامه می نویسید تابع URLDownloadToFile در API ویندوز هست که یک آدرس درخواستی
رو بصورت یک فایل ذخیره می کنه، صرفا یک دستور و خیلی ساده اما قابلیت هایش خیلی کمه.

برای ++C کتابخانه ای مثل libcurl هم هست، از نظر امکانات و قابلیت ها به مراتب قوی تره اما به کد نویسی
بیشتری نیاز داره، می توانید مستقیما خروجی را در یک رشته قرار بدهید، نیازی به ساختن فایل نیست.
 

mhabat

Member
سلام.ممنون بابت تابعی که معرفی کردید.

الان دستورشو به این شکل نوشتم:

کد:
  urldownloadtofile(nil,pchar("[URL]http://forum.majidonline.com.html"),pchar("c:\\TC\\index.txt"),0[/URL], nil)
فقط از فایل سرآمد windows.hاستفاده کنم؟(برای api?)

نمیشه کاری کرد که destرو خودمون در برنامه قرار بدیم اما sourcرو از وردی بگیریم؟

خیلی ممنون.
 

mhabat

Member
سلام.
این رو هم یه نگاه بنداز:
کد:
#include <wininet.h>
#pragma comment(lib, "wininet.lib") 

   CString yahoo_url= "[URL]http://forum.majidonline.com.html[/URL]"
CString Data;
   DeleteUrlCacheEntry(yahoo_url);  
HINTERNET IntOpen = ::InternetOpen("Sample", LOCAL_INTERNET_ACCESS, NULL, 0, 0);
HINTERNET handle = ::InternetOpenUrl(IntOpen, yahoo_url, NULL, NULL, NULL, NULL);
//HANDLE hFile   = ::CreateFile("C:\\TC\\link.txt", GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
char Buffer[1024];
DWORD dwRead =0;
while(::InternetReadFile(handle, Buffer, sizeof(Buffer), &dwRead) == TRUE)
{
   if ( dwRead == 0) 
    break;
   DWORD dwWrite = 0;
//   ::WriteFile(hFile, Buffer, dwRead, &dwWrite, NULL);
   Data+=Buffer;
}
//::CloseHandle(hFile);
::InternetCloseHandle(handle);
اگه سورس بالا کاره تابعی که معرفی کردین رو انجام بده میشه لینک رو از ورودی گرفت.

فقط نمی دونم سورسه همون کار رو انجام میده یا نه.

خیلی ممنون.
 

جدیدترین ارسال ها

بالا