O‘ZBEKISTON RESBUPLIKASI OLIY TA'LIM FAN VA INNOVATSIYALAR VAZIRLIGI __________________________ fanidan KURS ISHI MAVZU: C++ muhitida ma’lumotlarni kiritish chiqarishni formatlash usullari Bajardi: I -bosqich talabasi: ______________________________ Rahbar: _______________________________________(F. I. O.) Samarqand 2024 MUNDARIJA I. KIRISH .................................................................................................................. 3 II. ASOSIY QISM .................................................................................................... 5 1. C++ sintaksisi ..................................................................................................... 5 2. C++ tilida asosiy kirish/chiqish ......................................................................... 8 3. C++ tilida chiqarish operatori va uni formatlash (cout) .................................... 9 4. C++ tilida kiritish operatori va formatlab kiritish (cin) ................................... 11 5. C++ tilida chiqarish va formatlash funksiyasi (printf) .................................... 13 6. Spintf funksiyasi. ............................................................................................ 17 7. cout va printf funksiyalari o‘rtasidagi farqlar .................................................. 18 III. XULOSA ........................................................................................................... 20 IV. FOYDALANILGAN ADABIYOTLAR .......................................................... 21 2 I. KIRISH C++ - Bjarne Stroustrup tomonidan 1980-til boshlarida ishlab chiqilgan eng ko‘p ishlatiladigan va eng mashhur dasturlash tili. C++ - bu yuqori darajadagi va ob'ektga yo‘naltirilgan dasturlash tili. Ushbu til ishlab chiquvchilarga katta ilovalar va dasturiy ta'minotni ishlab chiqish, o‘yinlarni ishlab chiqish va operatsion tizimni dasturlash uchun toza va samarali kod yozish imkonini beradi. Bu C dasturlash tilining ob'ektga yo‘naltirilgan dasturlashni (OOP) o‘z ichiga olgan kengaytirilishi bo‘lib, kompyuterlar uchun dasturlarni ishlab chiqish uchun ishlatiladi. Ushbu C++ qoʻllanmasi C++ asoslari, C++ funktsiyalari, C++ sinflari, OOP va STL tushunchalari kabi C++ tilining barcha asosiy va ilgʻor mavzularini qamrab oladi. C++ eng mashhur platformalararo dasturlash tili boʻlib, u OS, oʻyinlar, elektron tijorat dasturlari va boshqalar kabi yuqori unumli ilovalar va dasturiy taʼminotlarni yaratish uchun ishlatiladi. U Bjarne Stroustrup tomonidan C tilining kengaytmasi sifatida ishlab chiqilgan. C++ tizim resurslari va xotira ustidan yuqori darajadagi nazoratni beradi. C++ - bu yuqori unumli ilovalar yaratish uchun ishlatilishi mumkin bo‘lgan o‘zaro faoliyat platformalar tili. C++ Bjarne Stroustrup tomonidan C tilining kengaytmasi sifatida ishlab chiqilgan . C++ dasturchilarga tizim resurslari va xotira ustidan yuqori darajadagi nazoratni beradi. Til 2011, 2014, 2017 va 2020 yillarda C++11, C++14, C++17, C++20 ga 4 ta katta marta yangilandi. C++ dunyodagi eng mashhur dasturlash tillaridan biridir. C++ tilini hozirgi operatsion tizimlarda, foydalanuvchi grafik interfeyslarida va o‘rnatilgan tizimlarda topish mumkin. C++ - bu ob'ektga yo‘naltirilgan dasturlash tili bo‘lib, u dasturlarga aniq tuzilma beradi va kodni qayta ishlatishga imkon beradi va ishlab chiqish xarajatlarini kamaytiradi. C++ portativ hisoblanadi va bir nechta platformalarga moslasha oladigan ilovalarni ishlab chiqish uchun ishlatilishi mumkin. C++ - bu qiziqarli va o‘rganish oson! C++ tili C , C# va Java tillariga yaqin boʻlgani uchun dasturchilar uchun C++ tiliga yoki aksincha oʻtishni osonlashtiradi. C++ - bu samaradorlik va tezlik muhim 3 bo‘lgan o‘yinlarni ishlab chiqish, virtual haqiqat, real vaqtda simulyatsiya va yuqori chastotali savdoda qo‘llaniladigan etakchi dasturlash tili. C++ ning bu qadar samarali bo‘lishining sabablaridan biri uning apparat bilan juda yaqindan ishlash qobiliyatidir. Bundan tashqari, ob'ektga yo‘naltirilgan dasturlash tili sifatida u rivojlanishda moslashuvchanlikni taklif qiladi. Bu tezlik va unumdorlikni muhokama qilib bo‘lmaydigan hollarda uni eng yaxshi tilga aylantiradi. C++ umumiy maqsadli dasturlash tili boʻlib, undan keng koʻlamli ilovalarni ishlab chiqishda foydalanish mumkin, masalan O‘yinni ishlab chiqish Virtual reallik Haqiqiy vaqtda simulyatsiya IoT (narsalar interneti) Brauzerlar, OS va ma'lumotlar bazalari Yuqori chastotali savdo C++ ni o‘rganish sizning martaba imkoniyatlaringiz uchun katta foyda keltiradi. Biroq, C++ tez rivojlanish va soddalik ustuvor bo‘lgan ayrim sohalar uchun eng yaxshi tanlov bo‘lmasligi mumkin. Misol uchun, agar siz veb-ishlab chiqish, mobil ilovalarni ishlab chiqish yoki avtomatlashtirish va ma'lumotlarni tahlil qilish uchun skriptlarga qiziqsangiz, C++ eng ideal variant bo‘lmasligi mumkin. Bunday hollarda veb-ishlab chiqish uchun JavaScript, mobil ilovalarni ishlab chiqish uchun Kotlin, Swift yoki Dart va skript yaratish va ma'lumotlarni tahlil qilish uchun Python kabi alternativalar ko‘proq mos kelishi mumkin. 4 II. ASOSIY QISM 1. C++ sintaksisi Sintaksis nima? Sintaksis deganda dasturlash tilida bayonotlar yozish qoidalari va qoidalari tushuniladi. Ularni dasturlash tilining tuzilishini belgilovchi grammatik qoidalar sifatida ham ko‘rish mumkin. C++ tili ham taqdim etuvchi funksiyalar uchun o‘z sintaksisiga ega. Turli xil iboralar ularning ishlatilishini ko‘rsatadigan turli xil sintaksisga ega, ammo C++ dasturlarida barcha dasturlarda amal qilinadigan asosiy sintaksis qoidalari ham mavjud. C++ dasturining asosiy sintaksisi. Biz quyidagi dastur yordamida asosiy C++ sintaksisi bilan tanishishimiz mumkin. 1-rasm. C++ sintaksisi 1. Sarlavha fayli: Sarlavha fayllari bizning dasturimizda foydalanadigan funktsiyalar va makroslarning ta'rifini o‘z ichiga oladi. Ular C++ dasturining yuqori qismida aniqlanadi. 1-qatorda biz #include <iostream> iborasidan foydalanib, kompilyatorga iostream sarlavhalari fayllari kutubxonasini qo‘shishni aytdik, unda biz kiritish va chiqarish uchun foydalangan cin va cout standart kiritish/chiqish oqimlarining 5 ta'rifini saqlaydi. #include preprotsessor direktivasi bo‘lib, biz sarlavha fayllarini import qilamiz. Sintaksis: #include < kutubxona_nomi > 2. Ismlar maydoni: C++ tilidagi nomlar maydoni biz identifikatorlarni aniqlaydigan soha yoki hududni ta'minlash uchun ishlatiladi. U ikkita identifikator o‘rtasidagi nom ziddiyatlarini oldini olish uchun ishlatiladi, chunki identifikator sifatida faqat noyob nomlardan foydalanish mumkin. 2-qatorda biz barcha standart kutubxona funktsiyalari aniqlangan standart nom maydoni bo‘lishini ko‘rsatish uchun std namespace iborasidan foydalandik. Sintaksis: using namespace std; C++ tilidagi nomlar bo‘shliqlari haqida ko‘proq ma’lumot olish uchun C++ tilidagi nomlar bo‘shliqlari maqolasiga qarang . 3. Asosiy funksiya: Funktsiyalar C++ dasturining asosiy qurilish bloklari bo‘lib, u qandaydir muayyan vazifani bajarish uchun ko‘rsatmalarni o‘z ichiga oladi. Funktsiya ta'rifi uning tanasida mavjud bo‘lgan ko‘rsatmalardan tashqari, uning qaytish turi va parametrlari haqida ma'lumotni ham o‘z ichiga oladi. C++ funksiyalari haqida ko‘proq bilish uchun C++ tilidagi funksiyalar maqolasiga qarang . №3 qatorda biz asosiy funktsiyani int main() sifatida aniqladik. Asosiy funksiya har qanday C++ dasturining eng muhim qismidir. Dasturning bajarilishi har doim asosiy funktsiyadan boshlanadi. Boshqa barcha funksiyalar asosiy funksiyadan chaqiriladi. C++ da asosiy funksiya bajarilish holatini ko‘rsatuvchi ba'zi qiymatlarni qaytarish uchun talab qilinadi. Sintaksis: int main() { ... kod .... return 0; } 6 4. Bloklar: Bloklar - bu { } qavs ichiga olingan iboralar guruhi . Ular identifikatorlar doirasini belgilaydi va odatda funksiyalar va boshqaruv bayonotlari tanasini qamrab olish uchun ishlatiladi. Asosiy funktsiyaning tanasi №4 qatordan 9-qatorgacha { } ichida joylashgan. Sintaksis: { // Funktsiyaning asosiy qismi return 0; } 5. Nuqtali vergul: Siz allaqachon sezgan bo‘lsangiz, yuqoridagi koddagi har bir bayonotdan keyin ( ; ) nuqtali vergul belgisi qo‘yiladi. U dastur bayonotining har bir satrini tugatish uchun ishlatiladi. Kompilyator bu nuqta-vergulni ko‘rganda, u o‘sha qatorning ishlashini tugatadi va keyingi qatorga o‘tadi. Sintaksis: kodlar; 6. Identifikatorlar: Biz identifikatorlardan o‘zgaruvchilar, funktsiyalar va boshqa foydalanuvchi tomonidan belgilangan ma'lumotlar turlarini nomlash uchun foydalanamiz. Identifikator katta va kichik alifbo belgilaridan, pastki chiziqdan va raqamlardan iborat bo‘lishi mumkin. Birinchi harf pastki chiziq yoki alifbo bo‘lishi kerak. Misol: int soni1 = 24; int soni2 = 34; num1 va num2 identifikatorlar, int esa ma'lumotlar turidir. 7. Kalit so‘zlar: C++ dasturlash tilida C++ dasturida ba'zi maxsus ma'nolar uchun ishlatiladigan ba'zi zahiralangan so‘zlar mavjud. Uni identifikatorlar uchun ishlatib bo‘lmaydi. Masalan, int, return va using so‘zlari dasturimizda ishlatiladigan kalit so‘zlardir. Bularning barchasi C++ tilida oldindan belgilangan ma'noga ega. C++ tilida jami 95 ta kalit so‘z mavjud. Bu ba'zi kalit so‘zlar. int void if while auto bool uchun bu statik yangi haqiqiy false case char sinfini buzadi. 7 8. Asosiy Chiqish soni: 7-qatorda biz standart chiqish oqimida (stdout) ikkita sonning yig‘indisini chiqarish uchun C++ da asosiy chiqish usuli bo‘lgan cout usulidan foydalandik. Sintaksis: cout << natija << endl; 2. C++ tilida asosiy kirish/chiqish C++ bizga kirish va chiqishni amalga oshirishning ko‘plab usullarini taqdim etadigan kutubxonalar bilan birga keladi. C++ da kirish va chiqish baytlar ketmaketligi shaklida amalga oshiriladi yoki odatda oqimlar deb nomlanadi. Kirish oqimi: Agar baytlar oqimining yo‘nalishi qurilmadan (masalan, klaviatura) asosiy xotiraga bo‘lsa, bu jarayon kiritish deb ataladi. Chiqish oqimi: Agar baytlar oqimining yo‘nalishi qarama-qarshi bo‘lsa, ya'ni asosiy xotiradan qurilmaga (ekran ekrani) bu jarayon chiqish deb ataladi. 2-rasm. C++ da kirish/chiqish 8 Kirish/chiqish operatsiyalari uchun C++ da mavjud sarlavha fayllari: 1. iostream : iostream standart kirish-chiqish oqimini bildiradi. Ushbu sarlavha fayli cin, cout, cerr va boshqalar kabi ob'ektlarning ta'riflarini o‘z ichiga oladi. 2. iomanip : iomanip kirish-chiqish manipulyatorlarini anglatadi. Ushbu fayllarda e'lon qilingan usullar oqimlarni manipulyatsiya qilish uchun ishlatiladi. Ushbu faylda setw, setprecision va boshqalar ta'riflari mavjud. 3. fstream : Ushbu sarlavha fayli asosan fayl oqimini tavsiflaydi. Ushbu sarlavha fayli fayldan kirish sifatida o‘qiladigan ma'lumotlarni yoki chiqish sifatida faylga yoziladigan ma'lumotlarni qayta ishlash uchun ishlatiladi. 4. bits/stdc++: Ushbu sarlavha fayli har bir standart kutubxonani o‘z ichiga oladi. 3. C++ tilida chiqarish operatori va uni formatlash (cout) C++ tilidagi cout obyekti iostream sinfining obyektidir . U iostream sarlavha faylida aniqlanadi . U standart chiqish qurilmasiga, ya'ni monitorga chiqishni ko‘rsatish uchun ishlatiladi. Bu standart C chiqish oqimi stdout bilan bog‘liq. Ekranda ko‘rsatilishi kerak bo‘lgan ma'lumotlar kiritish operatori (<<) yordamida standart chiqish oqimiga (cout) kiritiladi. Quyida cout obyektini amalga oshirish uchun C++ dasturi keltirilgan: #include <iostream> using namespace std; int main() { cout << "Bu mening kurs ishim"; return 0; } 9 cout iborasi ba'zi a'zo funktsiyalari bilan ham ishlatilishi mumkin: cout.write(char *str, int n): str dan birinchi N ta belgini o‘qishni chop eting. cout.put(char &ch): ch belgisida saqlangan belgini chop eting . cout.precision(int n): Float aniqligini N ga o‘rnatadi. Masalan: int main() { char gfg[] = "Welcome at GFG"; char ch = 'e'; cout.write(gfg, 6); cout.put(ch); return 0; } int main() { double pi = 3.14159783; cout.precision(5); cout << pi << endl; cout.precision(7); cout << pi << endl; return 0; } Chiqish: 3.1416 3.141598 10 qiymatlaridan foydalanganda kasr 4. C++ tilida kiritish operatori va formatlab kiritish (cin) C++ tilidagi cin obyekti iostream sinfining obyektidir . U standart kiritish qurilmasi, ya'ni klaviaturadan ma'lumotlarni qabul qilish uchun ishlatiladi. Bu standart C kirish oqimi stdin bilan bog‘liq. Chiqarish operatori (>>) kirishlarni o‘qish uchun cin ob'ekti bilan birga ishlatiladi. Ekstraksiya operatori klaviatura yordamida kiritilgan cin ob'ektidan ma'lumotlarni chiqaradi. Quyida cin obyektini amalga oshirish uchun C++ dasturi keltirilgan: #include <iostream> using namespace std; int main() { string s; cin >> s; cout << s; return 0; } cin bilan ekstraksiya operatorlari(>>) yordamida bir nechta o‘zgaruvchilarni kiritish mumkin. Quyida bir nechta foydalanuvchi ma'lumotlarini qabul qilish uchun C++ dasturi keltirilgan: int main() { string name; int age; cin >> name >> age; cout << "Name : " << name << endl; cout << "Age : " << age << endl; return 0; } 11 Cin quyidagi a'zo funktsiyalari bilan ham ishlatilishi mumkin: cin.getline(char *bufer, int N) : U N uzunlikdagi belgilar oqimini satr buferiga o‘qiydi , u (N - 1) belgilarni o‘qiganda yoki faylning oxirini yoki yangi qator belgisini (\n) topganda to‘xtaydi. Quyida cin.getline() ni amalga oshirish uchun C++ dasturi keltirilgan : int main() { char name[5]; cin.getline(name, 3); cout << name << endl; return 0; } Quyida cin.get() ni amalga oshirish uchun C++ dasturi keltirilgan : int main() { char ch; cin.get(ch, 25); cout << ch; } cin.read() - N uzunlikdagi belgilar oqimini o‘qiydi . Quyida cin.read() ni amalga oshirish uchun C++ dasturi keltirilgan : int main() { char gfg[20]; cin.read(gfg, 10); cout << gfg << endl; return 0; } 12 cin.ignore() - u kirish buferidagi bir yoki bir nechta belgilarni e'tiborsiz qoldiradi yoki o‘chiradi. Quyida cin.ignore() ni amalga oshirish uchun C++ dasturi keltirilgan : int main() { int x; char str[80]; cout << "Enter a number andstring:\n"; cin >> x; cin.ignore(numeric_limits<streamsize>::max(), '\n'); cin.getline(str, 80); cout << "You have entered:\n"; cout << x << endl; cout << str << endl; return 0; } Yuqoridagi dasturda agar cin.ignore() ishlatilmagan bo‘lsa, foydalanuvchi raqamni kiritgandan so‘ng qatorni kiritish uchun enter tugmasini bosgandan so‘ng, chiqish faqat kiritilgan raqam bo‘ladi. Dastur string kiritishni qabul qilmaydi. Ushbu muammoning oldini olish uchun cin.ignore() ishlatiladi, bu yangi qator belgisini e'tiborsiz qoldiradi. 5. C++ tilida chiqarish va formatlash funksiyasi (printf) C++ printf - bu stdout-ga satrni chop etish uchun ishlatiladigan formatlash funktsiyasi. C++ da printf ni chaqirishning asosiy g‘oyasi dasturda bo‘lgani kabi chop etilishi kerak bo‘lgan belgilar qatorini taqdim etishdir. C++ tilidagi printf formati spetsifikatsiyani ham o‘z ichiga oladi, uni bajarish vaqtida haqiqiy qiymat bilan almashtiriladi. 13 C++ printf prototipi: int printf(const char * formati, ...); Printf prototipi <cstdio> sarlavha faylida aniqlanadi. printf() funksiyasidan foydalanganda , u format tomonidan ko‘rsatilgan satrni standart stdout chiqishiga chop etadi. Formatda % bilan boshlanadigan va printf() funksiyasi bilan oʻzgaruvchilar qiymatlarini almashtiradigan baʼzi spetsifikatsiyalar ham boʻlishi mumkin. Oddiy qilib aytganda, ular printf() funksiyasiga qo‘shimcha argumentlar sifatida ishlaydi. C++ Printf parametrlari: C++ prototipi quyidagi parametrlarni o‘z ichiga oladi: const char: Konsolda chop etiladigan har qanday matn format: %d belgisi bilan boshlanadigan ixtiyoriy format spetsifikatoriga ega boʻlgan qatorga koʻrsatgich. C++ printf format spetsifikatsiyasining umumiy shakli quyidagicha: %[flags][width][.precision][length]spesifikator Yuqoridagi formatda: o %: Bu format spetsifikatsiyasining boshlanishini bildiruvchi yetakchi belgidir o Bayroqlar: konversiya harakatini o‘zgartiruvchi ixtiyoriy bir yoki bir nechta qiymat. Mavjud qiymatlar: o -: printf funktsiyasining natijasi sukut bo‘yicha o‘ngga asoslangan. Ushbu chap qiymat natijalarni oqlaydi o +: Bu hatto ijobiy qiymatlar uchun ham natija qiymatlariga belgi qo‘shadi o Bo‘sh joy: Agar qiymatga hech qanday belgi qo‘yilmagan bo‘lsa, natijaning boshiga bo‘sh joy qo‘shiladi o #: Bu konversiyaning muqobil shakli amalga oshirilishiga olib keladi o 0: Siz bu bayroqni butun sonlar va suzuvchi nuqtali raqamlar uchun qiymatlarni bo‘sh joy o‘rniga nol bilan to‘ldirish uchun ishlatasiz o Kenglik: Minimal kenglik maydonini aniqlash uchun * yoki butun son qiymatini qabul qiladigan ixtiyoriy maydon 14 o Aniqlik: ixtiyoriy argument aniqlikni *, butun qiymat yoki '.' dan keyin hech narsa qabul qilish orqali belgilaydi. ramzi o Uzunlik: Argument hajmini belgilaydigan ixtiyoriy parametr o Spesifikator: Bu maydon konvertatsiya formati spetsifikatsiyasini qabul qiladi C++ da Printf quyidagi format spetsifikatsiyalarini qabul qilishi mumkin. 15 3-rasm. Prinft funksiyaning format spetsifikatsiyalari 1-misol: #include <cstdio> int main(){ int i = 9; char name[] = "Simplilearn"; printf("i = %d \n", i); printf("Welcome to %s \n", name); return 0; } 16 2-misol: #include <cstdio> int main(){ char c = 'S'; float x = 7.0, y = 9.0; double d = 6.548; int i = 50; printf("The float division is : %.3f / %.3f = %.3f \n", x,y,x/y); printf("The double value is : %.4f \n", d); printf("Setting the width of c : %*c \n",3,c); printf("The octal equivalent of %d is %o \n",i,i); printf("The hex equivalent of %d is %x \n",i,i); return 0; } 6. Spintf funksiyasi. C++ tilidagi Sprintf() funksiyasi deyarli bitta asosiy farq bilan printf() funksiyasiga o‘xshaydi. C++ printf standart chiqishga yozganda, sprintf chiqishni satr buferiga yozadi. sprintf() funksiyasi prototipi: int sprintf(char * bufer, const char * formati, ...); Yuqoridagi prototipda parametrlar: 17 Bufer: Natijalar yoziladigan buferga ko‘rsatgich Format: fayl oqimiga yozilgan null bilan tugatilgan qatorga ko‘rsatgich C++ Stringf() funksiyasiga misol: Quyidagi misolda siz sprintf funksiyasidan foydalanib buferga satr yozasiz va formatlangan satrni chiqarasiz. Shuningdek, siz buferga yozilgan belgilarning umumiy sonini ko‘rasiz. #include <cstdio> #include <iostream> using namespace std; int main(){ char buf[100]; int return_Val; char my_name[] = "Simplilearn"; char topic[] = "tutorials"; return_Val = sprintf(buf, "Welcome to %s you can read various programming %s here!!", my_name, topic); cout << buf << endl; cout << "Total characters written are: " << return_Val << endl; return 0; } 7. cout va printf funksiyalari o‘rtasidagi farqlar C++ printf() funksiyasi odatda C dasturlashda qo‘llaniladi, lekin C++ da ham ishlashi mumkin. Biroq, cout ayniqsa C++ da qo‘shimcha hisoblanadi. Quyidagi jadvalda C++ printf va cout o‘rtasidagi sezilarli farqlar ko‘rsatilgan. 18 4-rasm. Cout va printf o‘rtasidagi farqlar 19 III. XULOSA Ushbu kurs ishimni qilish mobaynida men C++ tili va uning imkoniyatlari haqida batafsil ma’lumotlarga ega bo‘ldim. C++ tilidagi kiritsh chiqarish operatorlari, formatlab kiritish va formatlab chiqarishni o‘rgandim. C++ printf(), cout, cin, sprintf funksiyalari haqida hamma narsani bilib oldim. Natijalarni formatlash va ularni misollarda ishlatish uchun foydalanishimiz mumkin bo‘lgan turli format spetsifikatsiyalarini ham ko‘rdim va ularni amaliy qo‘llay olishni o‘rgandim. cout, cin, va printf funksiyalari C++ va C dasturlash tillarida matn va qiymatlarni chiqarish va o‘qish uchun amalga oshiriladigan standart konsol funktsiyalardir. cout va printf orasidagi asosiy farqidir, cout C++ da, printf esa C dasturlash tilida ishlatiladi. cin esa ham C++ da, ham C dasturlash tilida foydalanilishi mumkin. Bu funktsiyalardan cout va cin ning sintaksisi standart C++ kutubxonasidan kelgan iostream kutubxonasi orqali ta'minlanadi, printf esa standart stdio.h kutubxonasi orqali chaqiriladi. 20 IV. FOYDALANILGAN ADABIYOTLAR 1. A.X.Nishanov, U.U.Turapov. “C++ tilida dasturlash asoslari fani bo‘yicha o‘quv-uslubiy majmua”. Toshkent-2016; 2. J.Axmadaliyev, R.Holdarboyev. “ C++ tilini o‘rganish bo‘yicha o‘quvuslubiy majmua”. Andijon-2015; INTERNET RESUSRLARI 1. https://www.w3schools.com/cpp/cpp_output.asp 2. https://www.geeksforgeeks.org/cincout-vs-scanfprintf/ 3. https://www.programiz.com/cpp-programming/library-function/cstdio/printf 21