PDA

View Full Version : نحوه خواندن فایل های متنی unicode



RF.Ariyapoor
سه شنبه 29 بهمن 1387, 09:55 صبح
اگه از دوستان کسی میدونه که چه طور میشه تو c یا c++ فایل های متنی unicode را خوند خیلی ممنون میشم که کمکم بکنه
من می خوام یه برنامه بنویسم که یه فایل متنی رو که ممکن هستش که UTF-32 یا UTF-16 یا UTF-8 باشه رو بخونه و محتویات مثلا چند خط آول اون رو نشون بده

بعد می خواستم بدونم که آیا با توابع خاصی میشه این کار رو به سادگی کرد کرد یا اینکه من شنیدم اول فایل های unicode یه سری اطلاعات میذاره که مشخص میشه که unicode هستش و ما باید با توجه به این اطلاعات نحوه خوندنمون رو جوری تنظیم کنیم که متن درست رو بخونیم؟؟؟؟؟؟؟؟

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

sang9111
سه شنبه 29 بهمن 1387, 12:50 عصر
باید بگردی API پیدا کنی ببین این لینک ها به دردت می خورن
http://librdf.org/raptor/api/raptor-section-unicode.html

http://vb.mvps.org/hardcore/html/unicodeapifunctions.htm
دومی برای VB است ولی به درد می خوره یه نگاه بنداز

Nima_NF
سه شنبه 29 بهمن 1387, 14:59 عصر
از IsTextUnicode در ویندوز با هدر Windows.h می توانید استفاده کنید:



int isUnicode= IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_REVERSE_SIGNATURE ;

if (IsTextUnicode (pBufferStr, fileLength, &isUnicode))
{
// unicode
}
else
// Not unicode


در صورت نیاز می توانید خودتان دستی محتویات فایل را بررسی کنید، مثلا اگر اول آن byte-order mark/BOM با مقدار 0xFEFF باشد یونیکد هست یا اگر خودتان 0xFEFF را در اول فایل بریزید برنامه هایی مثل notepad کل فایل را به صورت یونیکد باز می کند و می خواند.

RF.Ariyapoor
سه شنبه 06 اسفند 1387, 10:41 صبح
ببین نیما جان من فعلا واسه utf-8 تونستم یه کارایی بکنم

به این شکل عمل کردم که اول 3 بایت اول متن رو میخونم که متوجه میشم فرمت utf-8 هستش
بعد یه بایت میخونم و بررسیش میکنم تا ببینم این کاراکتر تو 1 بایت هست یا دو بایت یا ...

در ضمن هر بایت رو به این شکل میخونم که یه متغییر char می گیرم و بعد یک بایت یک بایت از فایل می خونم

واسه یک بایتی ها که مشکلی نداره وقتی یک بایت میخونم بررسی میکنم که کاراکتر خونده شده اگر از 0x007F کم تر بود این بایت کد یک کاراکتر هستش و مثل ASCII میشه باهاش برخورد کرد ، که بعدش این کاراکتر رو چاپ میکنم

اگر بایتی که خوندم سه بیت پرارزشش 110 باشه متوجه میشم که این کاراکتر 2 بایتی هستش پس بایت بعدی رو میخونم
اگر بایت اول TMP1 باشه و بایت دوم TMP2 باشه به صورت زیر کد unicode اون رو میسازم

TMP1=TMP1 & 0x001F;
TMP2=TMP2 & 0x003F;
TMP3=TMP1;
for(int c=0;c<6;c++)
TMP3=TMP3*2;
TMP3=TMP3+TMP2;که خط اول و دوم من هر بایت رو با یه عدد mask کردم که اطلاعات اضافی رو از بین ببره بعد بایت پر ارزش رو ریختم تو یه متغییر 2 بایتی TMP3 (از نوع wchar_t یا هر متغییر 2 بایتی میتونه باشه)بعد با ضرب در 2 کردن 6 بار شیفت به چپ دادم و بعد بایت کم ارزش تر رو باهاش جمع کردم، که با این کار هم تونستم به درستی کد Unicode یک کاراکتر 2 بایتی رو بسازم.

تقریبا مشکل از اینجا شروع میشه

من میخوام این کاراکتر ها رو که میخونم بتونم یه جا چاپ کنم یا تو یه فایل ذخیره کنم. همونطور که گفتم با کاراکتر هایی که کد Unicode اونا یک بایتی بود مشکلی نداشتم اما واسه مثلا 2 بایتی ها دیگه هر جا چاپ میکردم یا تو یه فایل میریختم کاراکتر درست چاپ نمی شد.من حتی برنامه رو وقتی Debug کردم تو محیط اونجا که متغییر 2 بایتی رو میدیدم کاراکتر معادل اون رو اونجا نشون می داد(یعنی درست کد رو پیدا میکرد و همونجا هم میتونست کد Unicode رو تشخیص بده)اما جای دیگه من نمیتونستم کاراکتر رو درست چاپ کنم یا تو یه فایل بریزم.

بعد این همه توضیح میخواستم این رو بدونم که آیا تو محیط Console تابعی هستش که ما کد unicode رو بهش بدیم و کاراکتر معادلش رو چاپ کنه یا این که وقتی کد Unicode یه کاراکتر رو داریم چه طور میشه کاراکتر درست رو تو یه فایل ذخیره کرد؟؟

سوال دیگم اینه که من واسه ساختن متغییر های 3 یا 4 بایتی باید از چه متغییر هایی استفاده کنم که 3 یا 4 بایتی باشن

ممنون میشم کمکم کنید

در ضمن به دوستان بگم که از اونجایی که به ما از اول C و C++ رو تو محیط Console یاد دادن من فعلا با c++ تو محیط Console میتونم خوب کار کنم و با API ها و این چیزا فعلا آشنا نیستم و اصلا نمیتونم باهاشون کار کنم
ایشالا سر فرست باید این ها رو هم یاد بگیرم

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

ممنون

Nima_NF
چهارشنبه 07 اسفند 1387, 03:10 صبح
برای تبدیلات به multibyte به unicode و برعکس می توان از توابع wctomb / mbtowc / mbstowcs / wcstombs استفاده کرد. هر چند که این موارد جوابگوی کار شما نیست.

در ویندوز یونیکد به حالت UTF-16 هست، برای خواندن کارکترها از فایل به جای اینکه آن ها را به شکل char بخوانید و در آرایه ای از char بریزید، آن ها را باید به شکل wchar_t بخوانید که هر کارکتر را دو بایت در نظر می گیرد و می خواند. متاسفانه این کار با همان توابع استاندارد در سطح کنسول به راحتی نیست (حداقل بنده هم تا کنون با توابع استاندارد به جواب نرسیدم)


بعد این همه توضیح میخواستم این رو بدونم که آیا تو محیط Console تابعی هستش که ما کد unicode رو بهش بدیم و کاراکتر معادلش رو چاپ کنه یا این که وقتی کد Unicode یه کاراکتر رو داریم چه طور میشه کاراکتر درست رو تو یه فایل ذخیره کرد؟؟کلا کار کردن با unicode توسط توابع استاندارد بسیار سخت و پر از ابهامات و ضعف هست، پشتیانی کلی از unicode جدید هست و حتی در نسخه های اولیه ویندوز پشتیبانی نمی شود، پس زیاد نباید انتظار داشته باشید. کنسول حتی فونت پیش فرض برای مطالب unicode را نیز ندارد. پس بهترین راه استفاده از API های همان سیستم عامل هست. (در همان محیط کنسول)

از طریق API ها در همان محیط کنسول:



#include <windows.h>

DWORD bytesWritten ;
HANDLE hFile ;
int len ; //Note: set this to the length of pStr
TCHAR pStr[] = L"unicode text";
WORD byteOrder = 0xFEFF ; // UTF-16
pstr

if (INVALID_HANDLE_VALUE ==
(hFile = CreateFile (L"C:\\name.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)))
return FALSE ;

WriteFile (hFile, &byteOrder , 2, &bytesWritten, NULL) ;

WriteFile (hFile, pStr, len * sizeof (TCHAR), &bytesWritten, NULL) ;



در هر صورت اگر روش فوق مورد توجه شما نیست، کشف راه های جدید (و به قول دوستان، اختراع مجدد چرخه) توسط روش های استاندارد بر عهده شما، مثلا روش هایی مثل زیر:



basic_ofstream <wchar_t> wfile;
wfile.open( L"iotest.txt",ios_base::out | ios_base::app);
wfile.close();



در ضمن به دوستان بگم که از اونجایی که به ما از اول C و C++ رو تو محیط Console یاد دادن من فعلا با c++ تو محیط Console میتونم خوب کار کنم و با API ها و این چیزا فعلا آشنا نیستم و اصلا نمیتونم باهاشون کار کنمشما در بسیار ی موارد ناچارید که از API های سیستم عامل برای ورودی-خروجی استفاده کنید؛ API هایی که نام برده شد در همان محیط کنسول به کار می روند، فقط کافیست هدر فایل را include کنید و از تابع استفاده کنید.


سوال دیگم اینه که من واسه ساختن متغییر های 3 یا 4 بایتی باید از چه متغییر هایی استفاده کنم که 3 یا 4 بایتی باشنآرایه ای از char، دقت کنید که char لزوما کارکتر نیست، بلکه 1 بایت هست.