ساخت یک تابع با پارامتر نامحدود با استفاده از vector یا هر چیز دیگری در ++C - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

ساخت یک تابع با پارامتر نامحدود با استفاده از vector یا هر چیز دیگری در ++C

+1 امتیاز

سلام. من تصمیم گرفته بودم تابع printf رو بازسازی کنم طوری که بتونه متغیر string رو هم چاپ کنه.

من از الگوریتم زیر استفاده کردم :

گفتم ورودی ور که گرفت ، با یه آرایه (Array) اونو به کاراکتر تجزیه می کنم و بعد کاراکتر ها رو با دستور printf اصلی چاپ میکنم.

ولی :

1. من میخوام تعداد ورودی هاش نامحدود باشه. واسه همین از vector استفاده کردم. ولی نمیدونم درسته یا نه.

2. نمی دونم کاری که می خوام رو انجام میده یا نه.

اگه کسی میدونه بهم بگه این کد زیر درسته ؟ اگه درست نیس بهم روش پارامتر نامحدود با vector یا هر چیزی رو بگه خواهشا.

کد :

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
void Printf(vector<string> Massage)
    {
        for (unsigned int i = 0 ; i <= Massage.size() ; i++)
        {
            unsigned int Lenght = Massage[i].length();
            char MassageChar[Lenght] =;
            for(unsigned int j = 1 ; i <= Lenght ; j++)
            {
                printf("%c" , MassageChar[j]);
            }
        }
    }

 

سوال شده دی 19, 1393  بوسیله ی Arshia::Aghaei (امتیاز 108)   8 14 22
ویرایش شده دی 19, 1393 بوسیله ی Arshia::Aghaei

2 پاسخ

+1 امتیاز
 
بهترین پاسخ

میشه با استفاده از varidic template کاری که میخواهید رو انجام داد ولی  نوشتن تابع مربوط به print به این شکل کار درستی نیست به این دلیل که printf فقط برای ورودی های از پیش تعیین شده کار می کنه . و هر بار که یک کلاس مینویسد مجبور میشید کد این تابع رو تغییر بدید ! 

 

بجای این روش میشه  برای  کلاس یا فیلد یا هرچیزی که نیاز دارید یک operator<< با ورودی ostream بنویسید   به این شکل میشه با استفاده از cout کلاس رو چاپ کرد (یا  حتی بدون تغییر کد میشه کلاس رو داخل یک فایل بوسیله fstream نوشت )

مثلا برای وکتور :

#include <iostream>
#include <vector>
#include <string>

template <class T>
std::ostream& operator<<(std::ostream& stream, const std::vector<T>& vec) {
	for (int i = 0; i < vec.size(); i++) {
		stream << vec[i] << ' ';
	}
	stream << '\n';
	return stream;
}
int main() {
	std::cout << std::vector<int>{1, 2, 3};
	std::cout << std::vector<std::string>{"ab","cd","ee"};
}

برای کلاس هایی هم که ساختید به همین شکل میشه داخل فایل هدر مربوط به کلاس این تابع رو هم نوشت :

#include <iostream>
#include <fstream>
#include <vector>

class Test
{
public:
	Test(int a, int b) :var1_(a), var2_(b){}
	friend std::ostream& operator<<(std::ostream& stream, const Test& t);
private:
	int var1_;
	int var2_;
};
std::ostream& operator<<(std::ostream& stream, const Test& t){
	std::cout << "A : var1_ is : " << t.var1_ << " var2_ is : " << t.var2_ << '\n';
	return stream;
}
int main()
{
	Test t(5, 77);
	std::ofstream file("test.txt");
	file << t;//chap dar file
	std::cout << t;
}

مثال هایی این جا هم هست : نحوه نوشتن کلاس بوسیله cout

 

پاسخ داده شده دی 19, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
انتخاب شد دی 21, 1393 بوسیله ی Arshia::Aghaei
میشه طرز کار varidic template  رو بگین لطفا ؟
در ضمن. دو تا چیز :
1. تابع printf از cout بهتره جون هم سریع تر هست و چند تا مزیت دیگه هم داره که من بادم نیست.
2. نیازی به تعریف >> نسیت و با دستور زیر کار راحت میشه :
;ostream Output
اول این که printf  سریع تر نیست کافیه sync_with_stdio رو false کنید حتی من قبلا تست کردم سریع تر هم بوده !
مورد بعد اینه که cout صرفا برای log کردن یا debug کردن  استفاده میشه  که performace مهم نیست برای این کار .
بعد cout  مزیت هایی هم  مثل type safe بودن و thread safe بودن داره که خیلی مهم هستن .
الان ostream Output  دقیقا چطور یک کلاس رو cout می کنه !؟
شرمنده اشتباه شد.
برداشتم اشتباه بود.
سوال کلی من اینه :
چجوری یه تابع با ورودی نامحدود بسازیم ؟
حالا با vector یا همون چیزی که شما گفتین.
برای پارامتر نامحدود چند تا راه هست :
http://www.7khatcode.com/307/%D8%AA%D8%B9%D8%AF%D8%A7%D8%AF-%D8%A2%D8%B1%DA%AF%D9%88%D9%85%D8%A7%D9%86-%D9%87%D8%A7%DB%8C-%D9%86%D8%A7%D9%85%D8%AD%D8%AF%D9%88%D8%AF-%D8%AF%D8%B1-c
دو روش اول جدید تر هستن و از C++11 اضافه شدن روش سوم یعنی va_list چیزی هست که باهاش printf رو در زبان C نوشتن .
اون وقت یه سوال :
IDE من va_list نمیشناسه. چرا ؟
من از Code::Blocks استفاده میکنم.
من تست کردم  داخل codeblock مشکلی نداشت va_list
پروژه از نوع ++C ساختید  ؟
من هدری به اسم stdargs ندیدم.
البته یه stdarg.h بود. ولی فک کنم استاندارد نیست.
نه این هدر مشکلی نداره جزو کتابخانه های استاندارده . va_list داخل همین stdarg.h هستش.
خیلی ممنون. در ضمن (البته این ربطی به این موضوع نداره.)
میشه ببینین این مساله رو میتونین حل کنین ؟
http://www.7khatcode.com/6710/%D9%85%D8%B4%DA%A9%D9%84-%D9%86%DB%8C%D8%A7%D9%81%D8%AA%D9%86-%DA%A9%D8%A7%D9%85%D9%BE%D8%A7%DB%8C%D9%84%D8%B1-g-%D8%AF%D8%B1-eclipse-luna?show=6710#q6710
یه سوال :
 باید برای تعریف تابع با ورودی int در حلقه for موجود در بدنه تابع ، *char رو به *int تبدیل کرد ؟
نه اون نوعی هست که خونده میشه اگر int هست باید بنویسید int .
نمونه یک printf ساده با این روش : http://coliru.stacked-crooked.com/a/b9270d7807dc7460
این دوستمون یه خطو زیادی گذاشته :
#include <string>
وقتی iostream با دستور include احضار شده ، string هم include شده.
یه حرف دیگه : یکم درباره این حرفی که گفتین توضیح بهتر میدین . پس *char دلیل اینجوری نوشتنش چیه ؟
در ضمن : برای اون for ، بهتره به جای "str != "end از"" !=  str  استفاده کرد.
هدر string داخل gcc همراه iostream اضافه میشه ولی داخل visual studio( و بقیه کامپایلر ها مثل Clang) این طور نیست.
دلیل char* نوشتن این هست که ورودی های تابع از نوع char* هستند .
این جا چون مطمین هستیم همه از نوع char* هستند for گذاشته شده اگر این طور نباشه دقیقا باید نوع ورودی  ذکر بشه مثلا این مثال رو ببینید :
http://coliru.stacked-crooked.com/a/4cdab314839194bf
اون end هم درست هست ما چون نمی دونم چند تا ورودی داره تابع در اون مثال خاص  محبور هستیم یک رشته به اسم end بفرستیم که مشخص کننده  ورودی آخر باشه .
اگه null باشه بهتره
آره موافقم
0 امتیاز
پاسخ داده شده شهریور 4, 1394 بوسیله ی R0b3rtX99 (امتیاز 46)   5 9
...