प्रणाली ( "थामने"); - यह गलत क्यों है?


131

यहाँ एक सवाल है जो मुझे बिल्कुल समझ में नहीं आता है:

आदेश, system("pause");प्रोग्रामर को प्रोग्राम को पॉज़ करने और कीबोर्ड इनपुट जारी रखने के लिए प्रतीक्षा करने के तरीके के रूप में नए प्रोग्रामर्स को सिखाया जाता है। हालाँकि, यह कई अनुभवी प्रोग्रामरों द्वारा कुछ अलग-अलग डिग्री में नहीं किया जाना चाहिए।

कुछ लोग कहते हैं कि इसका उपयोग करना ठीक है। कुछ का कहना है कि इसका उपयोग केवल तब किया जाता है जब आप अपने कमरे में बंद हों और कोई देख नहीं रहा हो। कुछ का कहना है कि वे व्यक्तिगत रूप से आपके घर आएंगे और यदि आप इसका उपयोग करते हैं तो आपको मार देंगे।

मैं, बिना किसी औपचारिक प्रोग्रामिंग प्रशिक्षण के एक नया प्रोग्रामर हूं। मैं इसका उपयोग करता हूं क्योंकि मुझे इसका उपयोग करना सिखाया गया था। जो मुझे समझ नहीं आ रहा है, वह यह है कि अगर इसका इस्तेमाल नहीं किया जाना है, तो मुझे इसका इस्तेमाल करना क्यों सिखाया गया? या, फ्लिप की तरफ, क्या यह वास्तव में इतना बुरा नहीं है?

इस विषय पर आपके क्या विचार हैं?


संबं धत
लं क

5
जाहिरा तौर पर लोग वास्तव में कुशल होने के लिए अपने कॉल को रोकना पसंद करते हैं। दूसरे शब्दों में, "जल्दी करो और बंद करो!"
ली लुईविरे

63
आपको यह सिखाया गया था क्योंकि आम तौर पर शिक्षक बुरे प्रोग्रामर होते हैं
wich

कृपया अच्छे प्रश्न पूछने के लिए इस सलाह को पढ़ें: [ कैसे पूछें ], [सही प्रश्न लिखना ]।
आदि इनबार

9
@ पूरी तरह से बकवास।
माइकल चाउरडकिस

जवाबों:


85

क्योंकि यह एक प्लेटफ़ॉर्म-विशिष्ट हैक है, जिस पर वास्तव में प्रोग्रामिंग सीखने से कोई लेना-देना नहीं है, बल्कि इस पर ध्यान नहीं दिया गया है, बल्कि IDE / OS की एक विशेषता प्राप्त करने के लिए - विजुअल स्टूडियो से लॉन्च की गई कंसोल विंडो बंद हो जाती है जब प्रोग्राम ने निष्पादन समाप्त कर दिया है, और इसी तरह नए उपयोगकर्ता को अपने नए प्रोग्राम का आउटपुट देखने को नहीं मिलता है।

सिस्टम में बोडिंग ("पॉज़") विंडोज कमांड-लाइन "पॉज़" प्रोग्राम चलाता है और इसके लिए प्रतीक्षा करता है कि प्रोग्राम के निष्पादन को जारी रखने से पहले इसे समाप्त कर दिया जाए - कंसोल विंडो खुली रहती है ताकि आप आउटपुट पढ़ सकें।

एक बेहतर विचार यह होगा कि अंत में एक ब्रेकपॉइंट लगाया जाए और इसे डिबग किया जाए, लेकिन फिर से समस्या हो।


6
दृश्य स्टूडियो प्रोग्राम को दो मोड में चला सकता है: डिबगिंग के साथ या उसके बिना। डिबगिंग मोड में चलने पर यह पहले ब्रेक पॉइंट पर बंद हो जाएगा। यदि आपके पास कोई परिभाषित नहीं है तो यह प्रोग्राम को चलाएगा और कंसोल को बंद कर देगा। इसलिए, यदि आप चाहते हैं कि कंसोल प्रोग्राम बंद हो जाए, तो केवल ब्रेक-पॉइंट सेट करें, या, और भी बेहतर, इसे डिबगिंग के बिना चलाएं! यह प्रोग्राम को निष्पादित करेगा और कंसोल को रोक देगा।
इवान मेसिक जूल

यह केवल विजुअल स्टूडियो की एक विशेषता नहीं है - यदि आप विंडोज से कंसोल प्रोग्राम चलाते हैं (यानी कमांड प्रॉम्प्ट को लोड करने और इसे वहां से चलाने के विपरीत), तो यह तब भी बंद हो जाएगा जब उसने निष्पादन समाप्त कर दिया हो।
JBentley

2
−1 रे "विजुअल स्टूडियो से शुरू की गई कंसोल विंडो बंद हो जाती है जब प्रोग्राम का निष्पादन समाप्त हो जाता है", नहीं, केवल तब के लिए जब प्रोग्राम डीबगर में चलाया जाता है। पुन: "विंडोज कमांड-लाइन" पॉज़ "प्रोग्राम चलाता है", ऐसा कोई नहीं है ( pauseयह एक आंतरिक कमांड है cmd.exe)। बेहतर विचारों की सूची में भी गंभीर कमी है।
चीयर्स एंड हीथ। -

मुझे लगता है कि यह उत्तर एकमात्र ऐसा पहलू है जो इस पहलू पर छूता है कि यह एक समाधान है। यह एक विशिष्ट निष्पादन वातावरण के व्यवहार के आसपास काम करता है जो प्रोग्राम आउटपुट को पढ़ने से पहले टर्मिनल विंडो को बंद कर देता है। उस माहौल को ठीक करने के लिए आपको क्या करना चाहिए। यदि ऐसा नहीं किया जा सकता है, तो इस वर्कअराउंड का उपयोग करें, संभवतया केवल तभी IsDebuggerPresent()सही हो और इस वर्कअराउंड को ठीक से दस्तावेज़ित करें ("यह कोड यहाँ क्यों है?")।
उलरिच एकहार्ट

43

ये धीमा है। यह प्लेटफॉर्म पर निर्भर है। यह असुरक्षित है।

पहला: यह क्या करता है। "सिस्टम" को कॉल करना वस्तुतः विंडोज़ कमांड प्रॉम्प्ट में कमांड टाइप करने जैसा है। इस तरह की कॉल करने के लिए आपके आवेदन के लिए एक टन सेटअप और फाड़ है - और ओवरहेड बस हास्यास्पद है।

क्या होगा यदि "ठहराव" नामक कार्यक्रम को उपयोगकर्ता के पेट में रखा गया है? केवल कॉलिंग सिस्टम ("पॉज़") केवल गारंटी देता है कि "पॉज़" नामक एक प्रोग्राम निष्पादित किया गया है (आशा है कि आपके पास "पॉज़" नाम का निष्पादन योग्य नहीं है!)

बस अपने खुद के "ठहराव ()" फ़ंक्शन को लिखें जो _getch का उपयोग करता है। ठीक है, निश्चित रूप से, _getch प्लेटफ़ॉर्म पर निर्भर है (ध्यान दें: यह "conio.h" में परिभाषित किया गया है) - लेकिन यह बहुत अच्छा है system()कि अगर आप विंडोज पर विकसित कर रहे हैं और इसका एक ही प्रभाव है (हालांकि यह पाठ प्रदान करने की आपकी जिम्मेदारी है के साथ या तो)।

मूल रूप से: जब आप कोड की दो पंक्तियों को जोड़ सकते हैं तो बहुत सारी संभावित समस्याओं का परिचय क्यों हो सकता है और एक में अधिक लचीले तंत्र शामिल हैं?


61
प्लेटफ़ॉर्म निर्भरता के बारे में शिकायत करने वाले किसी व्यक्ति के लिए, यह सुझाव देना अजीब लगता है _getch, खासकर जब मानक सी ++ प्रदान करता है getchar
paxdiablo

33
मैं एक मानव के साथ बातचीत के लिए ओवरहेड की गणना में कुछ विडंबना महसूस करता
हूं

1
@Spagpants: शायद आप एक मानव से इनपुट प्राप्त करने और एक मानव में छवियों और ध्वनियों को उत्पन्न करने के बीच के अंतर को नहीं समझते हैं।
yzt

1
@ चेरसन्ध.-अल्फ - हम्? जब मैंने यह लिखा था, तो 8 साल पहले, मैंने बस एक मुद्दे को समाप्त कर दिया था, जो 'सिस्टम ("पॉज़")' के कारण हुआ था, क्योंकि प्रोजेक्ट का निष्पादन योग्य नाम "पॉज़" था और यह एक अनंत लूप में जाएगा। मेरी बात अब भी कायम है, मुझे यकीन नहीं है कि आप क्यों कह रहे हैं कि मैं गलत था।

2
@ paxdiablo getchar को एक इनपुट की आवश्यकता होती है और फिर एंटर दबाना होता है। _getch के लिए बस एक कीपर की आवश्यकता होती है, चाहे वह कोई भी हो। कंसोल पर _getch का अनुकरण करने के लिए आपको कंसोल मोड को बदलने के लिए कोड की 5-6 लाइनों की आवश्यकता होती है, और फिर इसे डिफ़ॉल्ट रूप से वापस बदल दें। यह समान नहीं है, यह अलग-अलग चीजें करता है। getchar, _getch का प्रतिस्थापन नहीं है।
बर्कैक

29
  • धीमा: इसमें बहुत सारे अनावश्यक विंडोज कोड और एक साधारण ऑपरेशन के लिए एक अलग प्रोग्राम के माध्यम से कूदना पड़ता है
  • पोर्टेबल नहीं: ठहराव कार्यक्रम पर निर्भर
  • अच्छी शैली नहीं: सिस्टम कॉल करना केवल तभी किया जाना चाहिए जब वास्तव में आवश्यक हो
  • अधिक टाइपिंग: सिस्टम ("ठहराव") गेटचेयर से अधिक लंबा है ()

एक साधारण गेटचार () बस ठीक करना चाहिए।


26

का उपयोग करना system("pause");Ungood Practice ™ है क्योंकि

  • यह पूरी तरह से अनावश्यक है
    जब आप दृश्य स्टूडियो, उपयोग से इसे चलाने के अंत में कार्यक्रम के कंसोल विंडो खुला रखने के लिए Ctrl+ F5पिछले दायां कोष्ठक में एक ब्रेकपाइंट डिबगिंग के बिना इसे चलाने के लिए, या फिर जगह }की main। तो, Visual Studio में कोई समस्या नहीं है। और निश्चित रूप से कोई समस्या नहीं है जब आप इसे कमांड लाइन से चलाते हैं।


  • जब आप कमांड लाइन से प्रोग्राम चलाते हैं तो यह समस्याग्रस्त और कष्टप्रद होता है। अंतःक्रियात्मक निष्पादन के लिए आपको अंत में एक कुंजी दबाना होगा जो भी उद्देश्य से न हो। और कुछ कार्य के स्वचालन में उपयोग के लिए जो pauseबहुत अधिक अवांछित है!

  • यह पोर्टेबल नहीं है।
    यूनिक्स-भूमि का कोई मानक pauseआदेश नहीं है।

pauseआदेश एक आंतरिक है cmd.exeके रूप में ग़लती से कम से कम एक अन्य जवाब में दावा किया जाता है, कमान और ओवरराइड नहीं किया जा सकता है। यानी यह एक सुरक्षा जोखिम नहीं है, और दावा है कि एवी कार्यक्रम इसे इस तरह से निदान करते हैं जैसे कि कमांड को ओवरराइड करने का दावा है (आखिरकार, एक C ++ प्रोग्राम इनवॉइस करने systemकी स्थिति में है कि कमांड इंटरप्रेटर ही कर सकता है, और अधिक)। इसके अलावा, जबकि पॉज़ करने का यह तरीका C ++ प्रोग्रामिंग के सामान्य मानकों द्वारा बेहद अक्षम है, जो कि नौसिखिए के कार्यक्रम के अंत में बिल्कुल भी मायने नहीं रखता है।

तो, इससे पहले कि जवाबों की भीड़ में दावे सही नहीं हैं, और मुख्य कारण जिसका आप उपयोग नहीं करना चाहते हैं system("pause") या आपके अंत में कोई अन्य प्रतीक्षा कमांड हैmain , ऊपर पहला बिंदु है: यह पूरी तरह से अनावश्यक है, यह बिल्कुल कोई उद्देश्य नहीं है , यह बहुत मूर्खतापूर्ण है।


1
कभी-कभी त्वरित परीक्षणों के लिए एक अनगूड प्रैक्टिस ™ की आवश्यकता होती है .... जिसे हम "त्वरित और गंदा" कहते हैं
माइकल हेपरती

22

सारांश में, इसे प्रोग्राम के निष्पादन को रोकना होगा और सिस्टम कॉल करना होगा और अनावश्यक संसाधनों को आवंटित करना होगा जब आप कुछ सरल का उपयोग कर सकते हैं। लोग सिस्टम ("PAUSE") का उपयोग करते हैं क्योंकि वे चाहते हैं कि कार्यक्रम तब तक प्रतीक्षा करें जब तक वे प्रवेश न करें, जब तक कि वे अपना आउटपुट नहीं देख सकते। यदि आप इनपुट के लिए प्रतीक्षा करने के लिए एक कार्यक्रम चाहते हैं, तो इसके लिए फ़ंक्शन बनाए गए हैं जो क्रॉस प्लेटफॉर्म और कम मांग वाले भी हैं।

इस लेख में आगे की व्याख्या ।


वाह, आप फिर से! क्या तुम यहाँ रहते हो? वैसे भी, धन्यवाद, मैं कुछ पढ़ने करूँगा। इस बीच, इस मामले पर आपके क्या विचार हैं?
फक

मेरे पास यही सवाल था जब मैंने पहली बार सी कुछ साल पहले शुरू किया था, और मुझे उसी लेख में बताया गया था। मैं व्यक्तिगत रूप से गेटचार () का उपयोग करता हूं।
जॉन टी।

हो वाह ... मैंने थोड़ी देर के लिए सी ++ नहीं किया है, लेकिन हाँ .. समान परिणाम प्राप्त करने के लिए निश्चित रूप से बेहतर तरीके हैं
न्यूटॉपियन

16

आप std::cin.get()से उपयोग कर सकते हैं iostream:

#include <iostream> // std::cout, std::cin
using namespace std;

int main() {
   do {
     cout << '\n' << "Press the Enter key to continue.";
   } while (cin.get() != '\n');

   return 0;
}

इसके अलावा, system('pause')धीमा है, और एक फ़ाइल भी शामिल है जिसकी आपको शायद आवश्यकता नहीं है stdlib.h:। यह प्लेटफ़ॉर्म-डिपेंडेंट है, और वास्तव में एक 'वर्चुअल' OS है।


3
मुझे System("pause")पहले वर्ष के प्रोग्रामिंग कोर्स में उपयोग करना सिखाया गया था , लेकिन मैं अपने कार्यक्रमों को अपने मैक पर चलाने में सक्षम होना चाहता था, इसलिए मुझे इसके बारे में सीखना था cin.get()
डेविएलेसल्स

10

क्योंकि यह पोर्टेबल नहीं है।

pause

एक विंडोज़ / डॉस केवल प्रोग्राम है, इसलिए यह आपका कोड लिनक्स पर नहीं चलेगा। इसके अलावा, systemआम तौर पर एक बहुत अच्छा तरीका है एक और प्रोग्राम को कॉल करने के रूप में नहीं माना जाता है - यह आम तौर पर उपयोग करने के लिए बेहतर है CreateProcessया forkया कुछ इसी तरह।


4

जैसा कि अन्य उत्तरों पर सूचीबद्ध है, कई कारण हैं जिनसे आप इससे बच सकते हैं। यह सब एक कारण से उबलता है जो बाकी को लूट लेता है। System()समारोह स्वाभाविक असुरक्षित / अविश्वसनीय है, और जब तक आवश्यक एक कार्यक्रम में नहीं पेश किया जाना चाहिए।

एक छात्र असाइनमेंट के लिए, इस शर्त को कभी पूरा नहीं किया गया था, और इस कारण से मैं इस कार्यक्रम को चलाने के बिना एक असाइनमेंट को भी विफल कर दूंगा अगर इस पद्धति का कॉल मौजूद था। (यह शुरुआत से स्पष्ट किया गया था।)


4

मेरे लिए बिना किसी कारण के बाहर निकलने से पहले इंतजार करना सामान्य नहीं है। एक कार्यक्रम जिसने अपना काम किया है, उसे अभी समाप्त होना चाहिए और अपने संसाधनों को अपने निर्माता को वापस सौंपना चाहिए।

एक भी चुपचाप काम के दिन के बाद एक अंधेरे कोने में इंतजार नहीं करता है, किसी को कंधे से बांधने के लिए इंतजार कर रहा है।


7
यह एक मूर्खतापूर्ण जवाब है। एक कार्यक्रम "अपना काम करना" का हिस्सा उपयोगकर्ता को अपने काम के परिणामों को प्रदर्शित कर रहा है। इसलिए इसे तब तक समाप्त नहीं होना चाहिए जब तक उपयोगकर्ता यह सूचित न कर दें कि वे इसके साथ समाप्त हो चुके हैं। एक प्रोग्राम जो उपयोगकर्ता के स्क्रीन से एक नैनोसेकंड गायब हो जाता है उसके परिणाम प्रदर्शित करने के बाद, यह बेकार है।
जेन्बले

1
@JBentley: मैंने परिणामों को प्रदर्शित करने के बाद स्थिति के बारे में बात की , यदि कोई हो। परिणाम प्रदर्शित करने के लिए, आपके टर्मिनल में सिग्नल, इंटरप्ट, टाइमर, स्क्रॉलबैक जैसे उपयुक्त पैटर्न मौजूद हैं। system("pause")अपने आप में कुछ भी प्रदर्शित नहीं करता है। एक कमांड लाइन इंटरफ़ेस प्रोग्राम जो कमांड लाइन से नहीं लगाया जाता है और बहुत जल्दी बंद हो जाता है, गलत तरीके से और गलत विकल्पों के साथ लागू किया जाता है, और गलत system("pause")तरीके से लगाए गए प्रोग्राम को दरकिनार करने के लिए उपयोग करना वास्तव में सही काम नहीं है।
सेबेस्टियन मच

1
मैं मतलब, बस कल्पना cat, less, vi, OpenOffice, Mathematica, GNU Octave, क्या हुआ अगर वे का उपयोग करेंगे system("pause")? यह कष्टप्रद होगा।
सेबेस्टियन मच

2
हां, यह कष्टप्रद होगा, लेकिन अब आप विशेष रूप से समस्याओं के बारे में बात कर रहे हैं system("pause"), जबकि आपका उत्तर "बाहर निकलने से पहले प्रतीक्षा करें" के बारे में बात करता है, जो एक अधिक सामान्यीकृत अवधारणा है। आपके द्वारा दिए गए कई उदाहरण वास्तव में "बाहर निकलने से पहले प्रतीक्षा करें", जब तक कि उपयोगकर्ता प्रोग्राम को सूचित नहीं करता कि वे इसे बाहर निकलना चाहते हैं। मैं मानता हूं कि system("pause")इसे प्राप्त करने का एक अच्छा तरीका नहीं है और यह कि बेहतर समाधान हैं, लेकिन यह वह नहीं है जो आपका जवाब कहता है।
जेबेंटली

1
@JBentley ओह, बिल्कुल: अगर एक देरी / प्रतीक्षा / शीघ्र कार्यक्रम के शब्दार्थ का हिस्सा है, pauseदूर!
हल्की

3
system("pause");  

यह गलत है क्योंकि यह विंडोज एपीआई का हिस्सा है और इसलिए यह अन्य ऑपरेशन सिस्टम में काम नहीं करेगा।

आपको C ++ मानक लाइब्रेरी से सिर्फ ऑब्जेक्ट का उपयोग करने का प्रयास करना चाहिए। एक बेहतर समाधान लिखना होगा:

cin.get();
return 0;

लेकिन अगर cinआपके कोड में अन्य s हैं तो यह भी समस्या पैदा करेगा । क्योंकि प्रत्येक के बाद cin, आप एक टैप करेंगे Enterया \nजो एक सफेद स्थान वर्ण है। cinइस चरित्र को अनदेखा करता है और इसे बफर ज़ोन में छोड़ देता है cin.get(), लेकिन , यह चरित्र बना रहता है। इसलिए प्रोग्राम का नियंत्रण लाइन तक पहुंच return 0जाता है और परिणाम देखने से पहले कंसोल बंद हो जाता है।
इसे हल करने के लिए, हम निम्नानुसार कोड लिखते हैं:

cin.ignore();  
cin.get();  
return 0;

वह थोड़ा भ्रामक है। system()मानक है और एमएस विंडोज के लिए विशिष्ट नहीं है। हालाँकि, pauseशेल कमांड एक डॉस विरासत है और आमतौर पर केवल वहाँ पाया जाता है।
उलरिच एकहार्ट

1

यहां एक कारण है कि आपको इसका उपयोग नहीं करना चाहिए: यह विंडोज पर चलने वाले अधिकांश एंटी-वायरस प्रोग्रामों को पेशाब करने जा रहा है यदि आप किसी अन्य मशीन पर प्रोग्राम पास कर रहे हैं क्योंकि यह एक सुरक्षा खतरा है। यहां तक ​​कि अगर आपके प्रोग्राम में केवल एक साधारण cout << "hello world\n"; system("pause"); इट्स रिसोर्स हैवी है और प्रोग्राम को cmd कमांड तक पहुंच मिलती है, जिसे एंटी वायरस खतरे के रूप में देखते हैं।


-1

सिस्टम का उपयोग करने के लिए समर्थक ("PAUSE"); अपने कार्यक्रम के छोटे हिस्से बनाते समय इसे स्वयं डिबग करने के लिए है। यदि आप प्रत्येक प्रक्रिया के दौरान और उसके बाद चर का परिणाम प्राप्त करने के लिए इसका उपयोग करते हैं, तो आप यह सुनिश्चित करने के लिए उपयोग कर रहे हैं कि वे ठीक से काम कर रहे हैं।

परीक्षण करने के बाद और बाकी हल के साथ इसे पूरे जोरों पर ले जाने के बाद आपको इन पंक्तियों को हटा देना चाहिए। उपयोगकर्ता द्वारा परिभाषित एल्गोरिथ्म का परीक्षण करने और यह आश्वस्त करने के लिए कि आप जो परिणाम चाहते हैं, उसके लिए उचित क्रम में चीजें कर रहे हैं।

किसी भी तरह से आप इसका उपयोग करने के बाद एक आवेदन में इसका उपयोग करना चाहते हैं और यह आश्वासन दिया है कि यह ठीक से काम कर रहा है। हालाँकि यह आपको सब कुछ का ट्रैक रखने की अनुमति देता है जो कि ऐसा हो रहा है। एंड-यूज़र ऐप्स के लिए इसका इस्तेमाल बिल्कुल न करें।


-3

यह सब स्टाइल की बात है। यह डिबगिंग के लिए उपयोगी है, लेकिन अन्यथा इसे प्रोग्राम के अंतिम संस्करण में उपयोग नहीं किया जाना चाहिए। यह वास्तव में स्मृति के मुद्दे पर कोई फर्क नहीं पड़ता क्योंकि मुझे यकीन है कि उन लोगों ने सिस्टम का आविष्कार किया था ("ठहराव") यह अनुमान लगा रहे थे कि इसका उपयोग अक्सर किया जाएगा। एक अन्य परिप्रेक्ष्य में, कंप्यूटर उनकी मेमोरी पर उन सब कुछ के लिए थ्रॉटल हो जाता है जो हम कंप्यूटर वैसे भी उपयोग करते हैं और यह डायनेमिक मेमोरी आवंटन जैसे प्रत्यक्ष खतरे को उत्पन्न नहीं करता है, इसलिए मैं इसे डीबगिंग कोड के लिए सुझाऊंगा, लेकिन और कुछ नहीं।


6
यह वास्तव में स्मृति के मुद्दे पर कोई फर्क नहीं पड़ता क्योंकि मुझे यकीन है कि उन लोगों ने सिस्टम का आविष्कार किया था ("ठहराव") यह अनुमान लगा रहे थे कि इसका उपयोग अक्सर किया जाएगा वास्तव में इसका कोई मतलब नहीं है। किसी ने इसे "आविष्कार" pauseनहीं किया था, इसे डीओएस बैच कार्यक्रमों में उपयोग के लिए डिज़ाइन किया गया था, इसे कभी भी इस तरह से उपयोग करने का इरादा नहीं था। इससे पहले कि वहाँ किसी को भी वाक्यांश टाइप करने के लिए पर्याप्त पागल था इससे पहले कि वहाँ बेहतर विकल्प थे system("pause");
विच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.