PDA

View Full Version : سوال: چه جوری میشه در StramReader فایل doc رو به صورت Right To Left خواند؟



sobaisobai
دوشنبه 25 مهر 1390, 20:48 عصر
سلام به همه

من یه فایل Doc رو میخونم اما وقتی از کلمه StartsWith استفاده میکنم line رو از چپ به راست میخونه .
کسی میدونه چه جوری میشه کاری کرد که از راست به چپ بشه یه line رو خوند؟
ممنون

mehdi.mousavi
سه شنبه 26 مهر 1390, 11:35 صبح
سلام به همه من یه فایل Doc رو میخونم اما وقتی از کلمه StartsWith استفاده میکنم line رو از چپ به راست میخونه . کسی میدونه چه جوری میشه کاری کرد که از راست به چپ بشه یه line رو خوند؟ ممنون

سلام.
فایل ها، همواره از ابتدا به انتها خونده میشن و ساختار فایل تعیین کننده چگونگی ذخیره داده ها در اون فایل هستش. در نتیجه، شما می تونید هر Line رو جداگانه بخونید، در صورت نیاز اونو Reverse کنید و جستجوی مورد نظر رو در رشته reverse شده انجام بدید. یا می تونید از Regular Expression (http://msdn.microsoft.com/en-us/library/2k3te2cs%28v=VS.100%29.aspx) ها استفاده کنید و کار رو به سادگی انجام بدید.

موفق باشید.

sobaisobai
سه شنبه 26 مهر 1390, 20:16 عصر
سلام
من line رو جدا میخونم و شرط گذاشتم گفتم اگه اولش مثلا 1 بود و اخرش علامت سوال تو یه مسیج باکس نشون بده.
فقط مشکلم اینجاست که line رو از چپ به راست میخونه
Regular رو هم که گفتید نمیدونم چیه.اگه بتونید رو فایلی که ضمیمه کردم توضیح بدید ممنون میشم.
بازم ممنون مدیر کل سایت

FastCode
چهارشنبه 27 مهر 1390, 22:21 عصر
خدا وکیلی میدونی مفهوم سوالت چیه؟
من میدونم چکار میخوای بکنی, ولی میتونم سوالت رو به ۵۰ شکل دیگه بنویسم که همین مفهوم رو بده, یک کلمش رو هم نفهمی.
تمرین دانشجویی هم ممنوعه.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace ReadTxt1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (File.Exists("1.doc"))
{
foreach (string u in System.IO.File.ReadAllLines("1.doc", System.Text.Encoding.Unicode))
{
if ((u.Length > 1) && (Char.IsDigit(u[0]) && u[u.Length-1] == '?'))
{
MessageBox.Show(u.ToString());//اینجا باید
//RightToLeft
//رو اضافه کنی.من توی لینوکس/مونو کلاس
//MessageBox
//رو ندارمش.
}
}
}
else if (!File.Exists("1.doc"))
{
MessageBox.Show("پیدا نشد");
}
}
}
}

sobaisobai
پنج شنبه 28 مهر 1390, 14:41 عصر
سلام دوست عزیز
من توی MessageBox مشکل ندارم که.
من تو خوندن یه خط Readline مشکل دارم
وقتی یه خط رو از فایل Doc میخونه از چپ به راست میخونه .حالا اگه من متن فارسی داشته باشم از انتها به ابتدا میخونه.
مشکل من اینه که چه جوری میشه متن رو از فایل Doc از راست به چپ بخونه؟

mehdi.mousavi
پنج شنبه 28 مهر 1390, 15:07 عصر
سلام.
حقیقتش ناراحت شدم کد شما رو دیدم و از اون بدتر، پاسخی که FastCode دادن حقیقتا منو حیرت زده کرد. شاید بخشی از این اشتباهات به دلیل مشارکت کمتر من و امثال من در تاپیک هایی باشه که در این سایت ایجاد میشه. شاید دلیلش چشم پوشی من از خروارها پاسخ نادرستی باشه که به تالارهای مختلف این سایت ارسال میشه. بطور کلی، من فردی نیستم که در برابر مطالب نادرست سکوت کنم، یا از کنار مطالبی که به نحوی باعث هدر رفتن وقت و هزینه اعضای سایت میشه به سادگی عبور کنم. ما اونهمه زمان صرف نکردیم که گفتگوی فنی شماره یک (http://barnamenevis.org/showthread.php?224704-%DA%AF%D9%81%D8%AA%DA%AF%D9%88%DB%8C-%D9%81%D9%86%DB%8C-%D8%B4%D9%85%D8%A7%D8%B1%D9%87-%DB%8C%DA%A9-%D8%A7%D8%B5%D9%88%D9%84-%D9%88-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%DA%A9%D8%AF-%D9%86%D9%88%DB%8C%D8%B3%DB%8C)، به این سادگی نادیده گرفته بشه و باز خروارها کد نادرست که با اصول اولیه یک کد صحیح بیگانه هستن، به این سایت ارسال بشه. جناب sobaisobai، این چه کدی هستش که شما نوشته اید؟

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace ReadTxt1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
if (File.Exists("1.doc"))
{
using (System.IO.StreamReader sr = new System.IO.StreamReader("1.doc", System.Text.Encoding.Unicode))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
string[] s = line.Split('\r');
foreach (string u in s)
{
for (int i = 0; i < 10; i++)
{
if (u.StartsWith((i).ToString()) && u.EndsWith("?"))
{
MessageBox.Show(u.ToString());
}
}
}
}
}
}
else if (!File.Exists("1.doc"))
{
MessageBox.Show("پیدا نشد");
}
}
}
}


مگه نگفته بودم که کد باید Refactor بشه؟


شما با چه استدلالی نام فایل رو سه بار در کد فوق آورده اید؟ اگر فردا اسم فایل تغییر کنه، باید تو کل Solution دنبال 1.doc بگردید و اونو با نام فایل جدید عوض کنید!
این چه if...else ای هستش که شما نوشته اید؟ یک بار چک کردید که فایل وجود داره یا نه، دیگه توی else که نباید همون شرط رو برعکسش رو چک کنید!
از همه بدتر، وقتی من پست اول رو دادم، فکر کردم منظورتون از doc "فایلهای سند متنی" هستن، نه فایلهای doc در Office Word. شما دارید یک فایل Composite باینری رو به string تبدیل می کنید، خط به خط می خونید و میگید چطوری راست به چپ بخونم؟ بعدش FastCode هم ادعا میکنه که متوجه کاری که شما میخواهید انجام بدید شده و ... (پوووووووف).

فایل مورد نظر رو رو در Notepad++ باز کنید، چنین چیزی می بینید:

76850

آیا این فایل قابل خوندنه؟ منظورم اینه که Human Readable هستش؟ البته که نیست! نوشته های من در این پست Human Readable هستن... محتوایی که با چشم قابل خوندن باشه رو بهش میگیم "متن" و مابقی فایل ها رو میگیم "Binary". شما نمی تونید (و نباید) با یک فایل باینری بصورت Text برخورد کنید. فایل Word شما حاوی این نوشته هاست:




1بفادزایزابیاتز؟

2بزللزازبازازاز.

3)سیبالطاطغای ؟

4.بازبیغابزغبز ؟



حالا شما می خواهید این نوشته ها رو خط به خط از فایل Office Doc استخراج کنید و در برنامه از اون استفاده کنید. برای اینکار، باید با ساختار فایل های DOC آشنا باشید و بدونید این 4 خطی که شما در اون فایل DOC نوشته اید، چطوری به 23KB اطلاعات تبدیل شده! فایل های DOC همونطوری که قبلا گفتم، فایل های Composite هستن. اگر این فایل رو Extract کنید، به Section های مختلفی در فایل می رسید. فایل شما،حاوی این Section هاست: CompObj، DocumentSummaryInformation، SummaryInformation، Table و WordDocument. حالا با بخش ها و ساختارهای تشکیل دهنده هر یک از این Section ها آشنا بشید تا ببینیم اون عبارات عجیبی که در فایل Word وارد کرده اید، کجای این فایل نگهداری میشن. این بخش از کار، نیازمند خوندن 500-600 صفحه Specs هستش که مطمئنا علاقه ای بهش ندارید...

اما خوشبختانه روش ساده تری نیز وجود داره و اون استفاده از Office Interop هستش. ابتدا به لیست Reference های پروژه، اسمبلی ی Microsoft.Office.Interop.Word رو اضافه کنید. سپس در ابتدای Namespace ها، namespace مورد استفاده Word App ها رو Insert کنید:

using Word = Microsoft.Office.Interop.Word;

به کدی که نوشته ام دقت کنید. اینجا، به Namespace مزبور اسمی داده ام، تا بتونم در ادامه برنامه از اون Alias استفاده کنم و مجبور نباشم کل Namespace رو هر بار بنویسم. همچنین، کد زیر رو نیز به namespace های مورد استفاده اضافه کنید:

using System.Runtime.InteropServices;

سپس، تابع زیر رو به برنامه اضافه کنید:


private string GetParagraphsInDoc(string filename)
{
Debug.Assert(!string.IsNullOrEmpty(filename));
StringBuilder p = new StringBuilder();

Word.Application app = new Word.Application();
Word.Document doc = app.Documents.Open(filename, ReadOnly: true, Visible: false);
doc.Activate();
app.Selection.WholeStory();

Word.Selection selection = app.Selection;
foreach (Word.Paragraph paragraph in selection.Paragraphs)
{
string text = paragraph.Range.Text;
if (!string.IsNullOrWhiteSpace(text))
p.Append(text);
}

Marshal.ReleaseComObject(app);
return p.ToString();
}


این تابع کارش چیه؟ فایل Office Word مورد نظر رو باز میکنه، کل Document رو Select میکنه و پاراگراف های موجود در اونو جدا میکنه. سپس در یک حلقه، پاراگراف ها رو بررسی میکنه که اگر null یا white-space نبودن، اونها رو به انتهای یک StringBuilder بچسبونه. در نهایت Reference به COM Object مربوطه رو آزاد میکنه و string مورد نظر رو برمیگردونه. دقت کنید که من کد فوق رو بر اساس .NET Framework 4.0 نوشته ام، چون از پاس کردن Missing Value های COM در C# بیزارم... در نهایت، تابع button1_Click شما بدین شکل باید تغییر کنه:


private void button1_Click(object sender, EventArgs e)
{
string filename = @"c:\1.doc";
if (!File.Exists(filename))
{
MessageBox.Show("پیدا نشد");
return;
}

string paragraphs = GetParagraphsInDoc(filename);
//Do whatever you'd like to do with lines...
}


اینجا، بعد از اینکه مطمئن شدیم فایل وجود داره، اونو به تابع فوق الذکر میدیم و محتوای پاراگراف های موجود در فایل Office Word رو دریافت می کنیم. حالا از اینجا به بعد می تونیم با این داده ها بصورت Text برخورد کنیم... برای اینکه خط به خط این string رو بخونیم، میتونیم با استفاده از کلاس StringReader بدین شکل عمل کنیم:


using (StringReader reader = new StringReader(paragraphs))
{
string line = reader.ReadLine();
}


موفق باشید.

FastCode
پنج شنبه 28 مهر 1390, 20:58 عصر
من هم همون فکر رو راجع به فایل doc کردم.

من فکر کردم MessageBox برعکسه.:ناراحت:

sobaisobai
پنج شنبه 28 مهر 1390, 21:28 عصر
سلام
FastCode (http://barnamenevis.org/member.php?109710-FastCode)جان ایراد نداره ادمی زاده دیگه اشتباه میکنه منم اشتباه کردم که مدیرکل مچمونو گرفت!!!!!!!!!!
فقط من یه مشکلی برام پیش اومد اونم اینه که چه جوری یه حلقه بذارم که تا وقتی به انتهای فایل متنی نرسیده Readline کنه؟

اگه کمکم کنی ممنون میشم:خجالت:

sobaisobai
پنج شنبه 28 مهر 1390, 22:39 عصر
سلام مجدد
داداش ReadAllLine واسه File هست.
من واسه کدی که mehdi.mousavi (http://barnamenevis.org/member.php?41233-mehdi.mousavi)گذاشته میخوام

sobaisobai
پنج شنبه 28 مهر 1390, 23:40 عصر
سلام
خودم پیداش کردم!!!!
while ((line = reader.ReadLine()) != null)
{
MessageBox.Show(line);
}