PDA

View Full Version : سوال: printf در Visual c++ 2005



بمب منطقی
شنبه 19 مرداد 1387, 16:50 عصر
با سلام خدمت اساتید این بخش:

معادل تابع printf تو VC2005 چیه که بشه خیلی راحت باسوئیچ هایی مثل %s %i %d \n \t و غیره بشه مقادیر مختلف با انواع مختلف داده رو تو یه Edit Box با فرمت دلخواه نمایش داد.

اگه میشه راهنمایی بفرمائید که دارم کچل میشم.

hoax3r
شنبه 19 مرداد 1387, 17:16 عصر
میتونی از sprintf استفاده کنی، این مثال رو ببین s1 متغییر خروجی هست


char s1[50];
sprintf(s1, "%08X\n%08X\n%08X", 124, 998877, 500);


البته تابع wsprintf هم هست که api های داخلی ویندوزه

شاد باشید

بمب منطقی
شنبه 19 مرداد 1387, 20:53 عصر
خدا عمرت بده .از راهنمائیت خیلی ممنونم. البته خود تابع sprintf رو که استفاده میکردم این warning رو میداد و بعد اجرا گاها !! وقتی کنترل به خط مربوط به تابع sprintf می رسید با یه fatal error برنامه خاتمه می یافت:
Sprintf was declared deprecated

علتش چیه؟ project رو بصورت MFC application ایجاد کردم.

ولی بعد از جستجو تو MSDN به تابع sprintf_s رسیدم و اونو با راهنمائی شما بدین صورت استفاده کردم و نتیجه مطلوب رو گرفتم:



char ch[40];
int i=52;
float j=2.5;
char str1[]="HELLO";
sprintf(ch,"STRING: \n%i\t%f/n%s",i,j,str1);
CString str(ch);
GetDlgItem(EDIT2)->SetWindowTextW(str);

hoax3r
شنبه 19 مرداد 1387, 21:07 عصر
این اررور به خاطر اینه که احتمالا هدر stdio.h رو تو برنامه تعریف نکردین

شاد باشید

بمب منطقی
یک شنبه 20 مرداد 1387, 02:48 صبح
میشه بگین کد زیر کجاش اشکال داره که بعد از اجرا ، اگه edit1 مقدارش Hello باشه بعد از اجرا Edit2 فقط کراکتر اول رو نمایش میده یعنی فقط H (در نظر داشته باشین که کد زیر داخل تابع رویداد کلیک یه دکمه قرار داره)

بازم ممنون از وقتی که برام گذاشتین



CString Cstr;
int L=GetDlgItem(EDIT1)->GetWindowTextLength();
GetDlgItem(EDIT1)->GetWindowText(Cstr);


char *str=new char[L];
sprintf_s(str,L,"%s",Cstr);

CString Cstr2(str);
GetDlgItem(EDIT2)->SetWindowText(Cstr2);

بمب منطقی
یک شنبه 20 مرداد 1387, 02:49 صبح
راستی مشکل قبلی با هیدر stdio رفع نشدا ! حالا بی خیال

hoax3r
یک شنبه 20 مرداد 1387, 10:02 صبح
در این مورد راستش من خیلی با MFC کار نکردم. زیاد بلد نیستمش، بزارین دوستان MFC کاربیان جواب بدن
شرمنده.

Nima_NF
یک شنبه 20 مرداد 1387, 15:02 عصر
وقتی از CString در MFC استفاده می کنید، تا جای ممکن از متدهای آن استفاده کنید تا راحت تر عمل کنید. (هر چند که همیشه توابع استاندارد C در اختیار شماست)
برای CString به جای sprintf از متد Format استفاده کنید تا دیگر نیازی به محاسبه طول و تخصیص حافظه نباشد:



CString Cstr;
char *chs = "test"; // for unicode use TCHAR

Cstr.Format("%s",chs);

در مورد اشتباه شما، نباید مستقیم Cstr را به جای char* جایگزین کنید بلکه باید از متد GetBuffer استفاده کنید:



sprintf_s (str, L ,"%s", Cstr.GetBuffer() );

ضمنا با توجه به کدهایتان، پروژه نباید به صورت یونیکد کامپایل شود...

موفق باشید

بمب منطقی
یک شنبه 20 مرداد 1387, 17:33 عصر
CString Cstr;
char *chs = "test"; // for unicode use TCHAR
Cstr.Format("%s",chs);

این کدی که شما فرمودین *char رو به cstring تبدیل میکنه که بجاش خیلی راحت میشه نوشت :


cstring str(chs)


ولی اونطور که متوجه شدم مشکل تو تابع sprintf_s هست که نمیتونه cstring رو به *char تبدیل کنه و با متد getbuffer هم مشکل حل نشد!


ضمنا با توجه به کدهایتان، پروژه نباید به صورت یونیکد کامپایل شود...
چرا؟!

در کل تو کدی که من نوشتم ابتدا نوع cstring به *char تبدیل میشه و بعد دوباره *char به cstring ، که مشکل در تبدیل cstring به *char هست. ولی متد format ای که شما فرمودین در تبدیل *char به cstring (یعنی تبدیل دوم) کاربرد داره.

Nima_NF
یک شنبه 20 مرداد 1387, 19:49 عصر
این کدی که شما فرمودین *char رو به cstring تبدیل میکنه که بجاش خیلی راحت میشه نوشت : ....خوب این طور که معلوم هست کلا اشتباه از موضوع برداشت کردید!

گفتید که پروژه شما MFC هست پس کلا تا جای ممکن char را فراموش کنید و با Cstring کارکنید .

شما رشته ای به صورت Cstring از ورودی دریافت می کنید یا اعداد دریافت می کنید و برای نمایش آن Cstring نیز نمایش می دهید:



CString CstrOut;
CString Cstr1("Hello"); // or Get it from EditBox
int num = 13;

CstrOut.Format("text: %s - number : %d \n", Cstr1, num);

پس نه از char استفاده کردیم نه از توابع استاندارد C مانند sprintf_s ، نه طول Editbox ،نه تخصیص حافظه. Format متد Cstring هست.

وقتی پروژه ای یونیکد باشد دیگر نباید از char استفاده کند بلکه باید از TCHAR استفاده کند و همین طور معادل یونیکد توابع استاندارد C و پیشوند L یا _T را نیز به کار ببرد در غیر این صورت کامپایلر خطا می دهد.

بمب منطقی
دوشنبه 21 مرداد 1387, 00:30 صبح
والا جریان از این قراره که برنامه ای که من نوشتم اول تو turbo c++ 3.0 کامپایلش کردم و با توابع کلاسیک c ،ولی بعد تصمیم گرفتم که اونو تو vc2005 کامپایلش کنم.از این جهت کل برنامه و توابع اونو بصورت یه کلاس generic تو یه پروژه MFC ایجادش کردم. تا ورودی متن از یه EDITBOX دریافت بشه و به کلاس مذکور تحویل داده بشه و خروجی هم بعد تحلیل کلاس (که کلیه متغیرها و انواع داده عضو اون از نوع کلاسیک سی پلاس پلاس هست) در یک EDITBOX دیگه نمایش داده بشه.

خوب با توجه به مطالب بالا و محدودیت های موجود پیشنهاد شما چیه؟

Nima_NF
دوشنبه 21 مرداد 1387, 02:21 صبح
خوب در این صورت مشکلی نیست، می توانید از همان توابع استاندارد C استفاده کنید.

فقط مشکلاتی که ذکر کردید برای من پیش نمی آید، باید برنامه را دید و تست کرد تا بتوان گفت در کجا اشتباه می کنید.
اگر پروژه zip شده را اینجا قرار دهید برایتان بررسی می کنم. ( جهت حفظ کپی رایت می توانید بخش های غیر مرتبط کدها را حذف کنید :D)

بمب منطقی
سه شنبه 22 مرداد 1387, 16:45 عصر
خیلی عجیبه این مشکل من تو VC6 ندارم.البته کد رو بدین شکل هم تغییر دادم:




CString Cstr,Ctr2;
GetDlgItem(EDIT1)->GetWindowText(Cstr);
char *str=new char[Cstr.GetLength()+1];
sprintf(str,"%s",Cstr);
Cstr2.Format(Str);
GetDlgItem(EDIT2)->SetWindowText(Cstr2);



تنها تفاوت خاص در اینه که بجای sprintf_s از sprintf و همچنین طول رشته کراکتری رو هم یکی بیشتر از طول Cstr در نظر گرفتم.