PDA

View Full Version : نوشتن یک تابع شبیه به printf



the_milad
دوشنبه 28 مهر 1393, 01:10 صبح
سلام، من می خوام یک تابع بنویسم که مانند printf کار کنه.
یعنی بهش یک رشته کاراکتر بدم و اون رشته رو در کنسول چاپ کنه، چطوری می تونم این کار و انجام بدم؟! کسی می تونه راهنمایی کنه؟!

StandardCode
دوشنبه 28 مهر 1393, 02:15 صبح
وارد مبحث سیستم پروگرمینگ میشیم. مثلا سورس تابع printf در گنو لینوکس :


__printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}

#target
دوشنبه 28 مهر 1393, 09:43 صبح
برای چاپ در کنسول میتونین از توابع APIاستفاده کنین اگه نمیخواین کتابخانه استاندارد C استفاده شه
اول باید کنسول رو به عنوان فایل باز کنین و توش بنویسین!

the_milad
دوشنبه 28 مهر 1393, 12:45 عصر
وارد مبحث سیستم پروگرمینگ میشیم. مثلا سورس تابع printf در گنو لینوکس :


__printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}


سلام این کد بالا را می تونید تتوضیح بدید؟ چرا قسمت پارامترها سه نقطه آورده شده؟!

StandardCode
دوشنبه 28 مهر 1393, 12:56 عصر
سلام این کد بالا را می تونید تتوضیح بدید؟ چرا قسمت پارامترها سه نقطه آورده شده؟!
بشین اینا رو بخون
http://en.wikipedia.org/wiki/Variadic_function
http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html

motherboard
دوشنبه 28 مهر 1393, 13:07 عصر
وارد مبحث سیستم پروگرمینگ میشیم. مثلا سورس تابع printf در گنو لینوکس :


__printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}

چرا HTML و C با هم تداخل پیدا کرده؟من که هر چی از زبان C بلد بودم از ذهنم پرید.

the_milad
دوشنبه 28 مهر 1393, 13:50 عصر
بشین اینا رو بخون
http://en.wikipedia.org/wiki/Variadic_function
http://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html

من دقیقا تو درک همین Variadic Function مشکل دارم. شما می تونی کمی در مورد آن برای من توضیح بدید؟

StandardCode
دوشنبه 28 مهر 1393, 14:54 عصر
من دقیقا تو درک همین Variadic Function مشکل دارم. شما می تونی کمی در مورد آن برای من توضیح بدید؟
تابعی که میتواند تعدا متغییری پارامتر ورودی بگیرد. برای استفاده از این ویژگی باید هدر stdarg.h را به برنامه خود الحاق نمایید که حاوی تایپ va_list و تابع va_start برای اینیشیلایز کردن تایپ va_list بعلاوه ماکرو va_arg که در هر فراخوانی پارامتر بعدی را بر میگرداند و تابع va_end که بهتر است وقتی کارمون تموم شد فراخوانی بشود. در اینجا لیست متغییر پارامترهای بعد از format را در قالب تایپ va_list و توسط تابع va_start اینیشیلایز کردیم, به عنوان آرگومان سوم آنرا تحویل vfprintf میدهیم.

اینم یه مثال که اگر خواستی روش تمرین کنی



#include<stdarg.h>
#include <stdio.h>
int printff (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}


int main(){
printff("%d ",1);
return 0;


}


میگم اگر زحمتی نیست یه سر به پست کتاب یا مرجع آموزش سی و سی پلاس پلاس (http://barnamenevis.org/showthread.php?101753-%DA%A9%D8%AA%D8%A7%D8%A8-%DB%8C%D8%A7-%D9%85%D8%B1%D8%AC%D8%B9-%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B3%DB%8C-%D9%88-%D8%B3%DB%8C-%D9%BE%D9%84%D8%A7%D8%B3-%D9%BE%D9%84%D8%A7%D8%B3/page4) بزن ببین ۲ تا پست آخری که مال من هست رو میبینید؟ چون من اونجا پست دادم اما دیده نمیشن به مدیر بخش هم گفتم میگه بقیه میبینن . حالا میخوام ببینم آیا شما پستی از من در آنجا میبینی؟

C3phalex1n_0x
دوشنبه 28 مهر 1393, 15:11 عصر
من دقیقا تو درک همین Variadic Function مشکل دارم. شما می تونی کمی در مورد آن برای من توضیح بدید؟

سلام، این نوع توابع، توابعی هستند که در آن ها هر چندتا آرگومان که بخواهید می توانید به آن عبور دهید. در کد زیر یک نمونه از این نوع پیاده سازی را مشاهده می کنید.
#include <stdarg.h>
#include <stdio.h>

int
add_em_up(int count, ...)
{
va_list ap;

va_start(ap, count); /* Initialize the argument list. */
auto sum = 0;

for (auto i = 0; i < count; i++)
sum += va_arg(ap, int); /* Get the next argument value. */

va_end(ap); /* Clean up. */
return sum;
}

int main(void)
{
/* This call prints 16. */
printf("%d\n", add_em_up(3, 5, 5, 6));

/* This call prints 55. */
printf("%d\n", add_em_up(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

return 0;
}

به منظور اینکه بتوانید از این ویژگی استفاده کنید باید سرآیند فایل stdarg.h را به برنامه خود include یا وارد کنید. هنگامی که این کار را انجام دادید باید تابع مد نظرتان که نمی دانید چند آرگومان به آن عبور داده خواهد شد را به شکل زیر پیاده سازی کنید. در این قسمت من کد بالا را فقط تشریح خواهم کرد.
int add_em_up(int count, ...)

این علامت سه نقطه به کامپایلر می گوید که این تابع می تواند بی نهایت آرگومان مشابه int count دریافت کنید. سپس وارد پیاده سازی تابع می شوید. در قسمت اول پیاده سازی تابع شما باید یک متغییر تعریف کنید که لیست آرگومان ها را در خود نگه داری کند. بدین منظور می توانید از کلمه کلیدی va_list به شکل زیر استفاده کنید.
va_list ap;

سپس ap را با تعداد آرگومان های عبور داده شده به تابع مقداردهی اولیه می کنید.
va_start(ap, count); /* Initialize the argument list. */

سپس می توانید با استفاده از va_arg به شکل زیر به محتویات هر آرگومان دسترسی پیدا کنید.
va_arg(ap, int)

motherboard
دوشنبه 28 مهر 1393, 15:21 عصر
اهههههههه:متعجب:
یکی به من بگه این تگ div در این کد چی کار می کنه؟

<div style="text-align: left;">__printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}</div>



البته اگه ممکنه :قلب:

StandardCode
دوشنبه 28 مهر 1393, 15:32 عصر
اهههههههه:متعجب:
یکی به من بگه این تگ div در این کد چی کار می کنه؟

<div style="text-align: left;">__printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}</div>



البته اگه ممکنه :قلب:
گیر دادی ها! موقع گذاشتن کد دیدم کد درهم برهم از نواز ابزار align left
رو زدم بعد گذاشتمش توی تگ [cpp] . ولی خوب همون تگ cpp کافیش بود و align left نمیخاست/

کامبیز اسدزاده
دوشنبه 28 مهر 1393, 15:35 عصر
اهههههههه:متعجب:
یکی به من بگه این تگ div در این کد چی کار می کنه؟

<div style="text-align: left;">__printf (const char *format, ...)
{
va_list arg;
int done;


va_start (arg, format);
done = vfprintf (stdout, format, arg);
va_end (arg);


return done;
}</div>



البته اگه ممکنه :قلب:

به احتمال بسیار قوی خطا از ادیتور سایت هستش و مشخصه کد از روی یک صفحه HTML کپی و در اینجا پست شده.

یعنی در اصل این کد


<div style="text-align: left;">

</div>


ربطی به کد اصلی نداره و دقیقا مشکل همون مشکل ادیتوری هستش که بارها در بارش انتقاد و پیشنهادات جهت رفع مشکلاتش شده.

بهروز عباسی
دوشنبه 28 مهر 1393, 22:13 عصر
بوی کاربر مولتی یوزر میاد :D

برای انجام این کار شما میتونید مستقیم از وقفه های اسمبلی استفاده هم کنید؛ کاری که برای نوشتن سیستم عامل ها از صفر انجام میشه.

the_milad
سه شنبه 29 مهر 1393, 09:39 صبح
بوی کاربر مولتی یوزر میاد :D

برای انجام این کار شما میتونید مستقیم از وقفه های اسمبلی استفاده هم کنید؛ کاری که برای نوشتن سیستم عامل ها از صفر انجام میشه.

من دوست دارم با جزئیات کارکرد مثلا دستورات printf و scanf و... آشنا شم. مثلا چطوری اینا پیاده سازی شدن و من چطوری می تونم یک تابع مثل اینا ایجاد کنم؟ کلا می خوام با جزئیات سطح پایین آشنا شم، اما نمی دونم باید از کجا مطالعه کنم تا بتونم همچین توابعی رو برای خودم بنویسم و استفاده کنم. زبان سی و اسمبلی رو هم بلد هستم. در مورد سیستم عامل هم کمی اطلاعات دارم.

hamid_hr
سه شنبه 29 مهر 1393, 13:23 عصر
خب برا جزئیات بیشتر برو اسمبلی رو یاد بگیر
اونوقت میتونی با وقفه ها این توابعو پیاده سازی کنی

the_milad
سه شنبه 29 مهر 1393, 14:41 عصر
خب برا جزئیات بیشتر برو اسمبلی رو یاد بگیر
اونوقت میتونی با وقفه ها این توابعو پیاده سازی کنی
بهترین منبع برای یادگیری زبان برنامه نویسی اسمبلی x86 و x64 چی هست؟

motherboard
سه شنبه 29 مهر 1393, 15:14 عصر
بهترین منبع برای یادگیری برنامه نویسی خواندن منابع و کتب انگلیسی زبان است و واقعا قابل قیاس با منابع فارسی نیست.البته برای یادگیری وب و تکنیک های ان منابع فارسی زیادی وجود داره و دست دست اندر کاران واقعا درد نکنه..اما برای یکسری زبان ها مانند ++C و اسمبلی منابع زیاد کامل و جالبی وجود نداره.از من می شنوی بچسب به خواندن کتب و سایت های انگلیسی زبان که واقعا عالی هستند. من یکی که دیگه با کتاب های فارسی حال نمی کنم و کلا دیگه عادت کردم مطالب برنامه نویسی رو از منابع انگلیسی یاد بگیرم. موفق باشید.

the_milad
سه شنبه 29 مهر 1393, 18:10 عصر
بهترین منبع برای یادگیری برنامه نویسی خواندن منابع و کتب انگلیسی زبان است و واقعا قابل قیاس با منابع فارسی نیست.البته برای یادگیری وب و تکنیک های ان منابع فارسی زیادی وجود داره و دست دست اندر کاران واقعا درد نکنه..اما برای یکسری زبان ها مانند ++C و اسمبلی منابع زیاد کامل و جالبی وجود نداره.از من می شنوی بچسب به خواندن کتب و سایت های انگلیسی زبان که واقعا عالی هستند. من یکی که دیگه با کتاب های فارسی حال نمی کنم و کلا دیگه عادت کردم مطالب برنامه نویسی رو از منابع انگلیسی یاد بگیرم. موفق باشید.

من از همون اول کتاب زبان اصلی می خوندم و منظورم از منبع، منبع انگلیسی بود.

بهروز عباسی
سه شنبه 29 مهر 1393, 18:26 عصر
من دوست دارم با جزئیات کارکرد مثلا دستورات printf و scanf و... آشنا شم. مثلا چطوری اینا پیاده سازی شدن و من چطوری می تونم یک تابع مثل اینا ایجاد کنم؟ کلا می خوام با جزئیات سطح پایین آشنا شم، اما نمی دونم باید از کجا مطالعه کنم تا بتونم همچین توابعی رو برای خودم بنویسم و استفاده کنم. زبان سی و اسمبلی رو هم بلد هستم. در مورد سیستم عامل هم کمی اطلاعات دارم.


انقدر سطح پایین هم دردسر داره :D ، همونطور که گفتم این کارو معمولاً موقع طراحی اولین libهای سیستم عامل انجام میدن چون اون موقع ما نمی تونیم "هیچ کدوم" کتابخونه های زبان C رو استفاده کنیم(یعنی نوشتن برنامه بدون Include کردن چیزی !) و به همین خاطر باید تموم این توابع رو با اسمبلی بنویسیم.
مثلا تابع مذکور اینطوری تعریف میشه (مثلا توی هدر st.h):

void printf(args,...)
{
asm
{
//; Print text in console using assembly !
}
}


بعد همین st.h رو هرجایی که لازمه توی خروجی چیزی نمایش داده بشه استفاده میکنیم !.

توجه داشته باش که این کارها رو فقط توی همین شرایط خاص میتونی آزادانه انجام بدی! نه در همه حال ! توی ویندوز شما نمیتونی بسیاری از وقفه ها (از جمله وقفه های بایوس) رو استفاده کنی (البته تو User-Land) به همین خاطر هم خیلی از این توابع رو نمیتونی به این شکل (سطح پائین) پیاده سازی کنی و "مجبوری" از توابع ارائه شده توسط خود سیستم عامل استفاده کنی.
با این حال اگر باز هم به این مسائل علاقه مندی بهتره مقالاتی که در مورد نوشتن سیستم عامل ها وجود داره بخونی (یادمه توی Codeproject و شبگرد (خدا بیامرز) یه چیزایی بود).

موفق باشید.

rahnema1
سه شنبه 29 مهر 1393, 22:10 عصر
برای چاپ در کنسول میتونین از توابع APIاستفاده کنین اگه نمیخواین کتابخانه استاندارد C استفاده شه
اول باید کنسول رو به عنوان فایل باز کنین و توش بنویسین!

انقدر سطح پایین هم دردسر داره :D

فکر کنم در این سطح نیازی به اسمبلی نباشه به قول آقای عباسی دردسر داره
همون طور که #target هم اشاره کردند میتونید از تابع های API استفاده کنید
در واقع در ویندوز در پشت پرده تابع printf از تابع های WIN32API جهت کار خودش استفاده می کنه
روند این کار اینجوریه که اول از بافر برنامه (یعنی همون آرایه char ) توی بافر stdout نوشته میشه و از اونجا به بافر کنسول منتقل میشه حالا به قول دوستمون مستقیما هم میشه به صورت میانبر توی بافر کنسول نوشت
اینجا می تونید مراجعه کنید در خصوص I/O و فایل و کنسول :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx

حالا اگه شما به این هم قانع نباشید و بخواهید به سطوح پایین تر برید لازم میشه که کنسول را خودتون پیاده سازی کنید که نیاز به thread و گرافیک و .. پیدا می کنید که باز هم اینها سطوح پایین تر دارند که اسمبلی لازم می شه

the_milad
سه شنبه 29 مهر 1393, 22:31 عصر
فکر کنم در این سطح نیازی به اسمبلی نباشه به قول آقای عباسی دردسر داره
همون طور که #target هم اشاره کردند میتونید از تابع های API استفاده کنید
در واقع در ویندوز در پشت پرده تابع printf از تابع های WIN32API جهت کار خودش استفاده می کنه
روند این کار اینجوریه که اول از بافر برنامه (یعنی همون آرایه char ) توی بافر stdout نوشته میشه و از اونجا به بافر کنسول منتقل میشه حالا به قول دوستمون مستقیما هم میشه به صورت میانبر توی بافر کنسول نوشت
اینجا می تونید مراجعه کنید در خصوص I/O و فایل و کنسول :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx

حالا اگه شما به این هم قانع نباشید و بخواهید به سطوح پایین تر برید لازم میشه که کنسول را خودتون پیاده سازی کنید که نیاز به thread و گرافیک و .. پیدا می کنید که باز هم اینها سطوح پایین تر دارند که اسمبلی لازم می شه

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

rahnema1
سه شنبه 29 مهر 1393, 22:40 عصر
در مورد ویندوز سیستم عاملی اپن سورس هست به نام reactos که دارند توسعه اش میدند که شبیه ویندوزه می تونید به سورس اون مراجعه کنید کتاب Windows Internals هم درخصوص ویندوز توضیح داده در مورد لینوکس هم می تونید به یکی از توزیعهای لینوکس مراجعه کنید در ضمن ما تالار سیستم عامل هم در این سایت داریم که فکر کنم بیشتر در خصوص لینوکس کار می کنند