1 / 44

Programozási Nyelvek (C++) Gyakorlat Gyak 03.

Programozási Nyelvek (C++) Gyakorlat Gyak 03. Török Márk tmark @ caesar.elte.hu D-2.620. 1. Kódelemzés. Feladat: Olvassunk be betüket a sabványos bemenetről (a – z), és írjuk ki a nagybetűs párjukat (A – Z). Különleges karakterek, nagybetűk helyben maradnak, angol abc-vel dolgozunk.

lew
Télécharger la présentation

Programozási Nyelvek (C++) Gyakorlat Gyak 03.

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programozási Nyelvek (C++) GyakorlatGyak 03. Török Márk tmark@caesar.elte.hu D-2.620 1

  2. Kódelemzés • Feladat:Olvassunk be betüket a sabványos bemenetről (a – z), és írjuk ki a nagybetűs párjukat (A – Z).Különleges karakterek, nagybetűk helyben maradnak, angol abc-vel dolgozunk.

  3. Tömbök

  4. Konstansokról • Nézzünk egy példát: • strlen implementálása: intstrlen( char* s ) { char *p = s; while ( *p != '0' ) { ++p; } // hello world0, előre zavarom a p-t. return p - s; // két pointer különbsége az adott szó hossza. }

  5. Konstansokról • Mi van akkor, ha: intstrlen( char* s ) { char *p = s; while( *p = '0' ) // hiba lehetőség! { ++p; } return p - s; }

  6. Konstansokról • Javítsuk: intstrlen( constchar* s ) { constchar *p = s; // csak együtt lehetnek! while ( *p = '0' ) // így már szemantikai hiba! { ++p; } return p - s; }

  7. Kódelemzés • Áttekintés: • Kezdjünk egyből C++-vel! • Ha egy C++ programot írunk, érdemes a biztonságra törekedni. • Azaz, kerüljük, hogy egyszerre megírjuk az egészet, és csak utána fordítunk! • Részenként kell csinálni! (és úgy fordítani!) • Ezek a lépések: • Elso lépésként megnézzük, hogy a stdinputot másolja át a stdoutputra! • Második lépésként nézzük meg, hogy felismerie a kisbetűt. • Majd harmadik lépésként alakítsuk a felismert kisbetűket nagybetűssé!

  8. Kódelemzés #include<iostream> int main() { charch; std::cin >> std::ios_base::noskipws; while( std::cin >> ch) { std::cout << ch; } return0; }

  9. Kódelemzés • Megoldás:#include<iostream>usingnamespacestd;int main() {charch;while (cin >> noskipws >> ch) {cout << …(???) } } • noskipws: io-manipulátor, nem ugorja át a whitespaceket (space, tab,…), ennek testvére a skipws, mely átugorja azokat.

  10. Kódelemzés • Fordul! Yeehaaa! • Kisbetűk felismerése a feladat!

  11. Kódelemzés #include<iostream> int main() { charch; std::cin >> std::ios_base::noskipws; while ( std::cin >> ch ) { if ( 'a' <= ch && ch <= 'z') // #1 { std::cout << ch + 'A' - 'a'; // #2 } else { std::cout << ch; } } return0; }

  12. Kódelemzés • #1 Kérdés: Működik-e char-ok között a <= operator? Mivel mindegyik int-re konvertálódik, így az ascii kódok között történik meg a <= vizsgálat! • #2 Kérdés: Hogyan konvertáljuk a karaktereket nagybetűvé?Mivel ascii-val dolgozunk, ezért ch + 'A' - 'a'

  13. Kódelemzés • int-ek kerülnek kiírásra, mivel a + és - szintén nincs értelmezve a char-ok között! • ascii kód íródik ki, ahelyett, hogy char érték íródott volna ki!

  14. Kódelemzés #include<iostream> int main() { charch; std::cin >> std::ios_base::noskipws; while( std::cin >> ch ) { std::count << 'a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch; } return0; }

  15. Kódelemzés • Mi történt? • A kiértékelés miatt precedenciaproblémák vannak!

  16. Kódelemzés #include<iostream> int main() { charch; std::cin >> std::ios_base::noskipws; while( std::cin >> ch ) { std::count << ('a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch); } return0; }

  17. Kódelemzés • Továbbra is számok íródnak ki! Meglepő módon most már a betűk helyett is számok íródnak ki! • T1 T2 ==> T • Fordítási időben meg kell mondania, hogy melyik kiíró-operátort válassza meg! A fordítónak fordítás alatt tudnia kell, hogy milyen a kifejezés típusa! • Itt: int opchar=> int

  18. Kódelemzés • Promotionrules: • short, char => int • float => double • double => long double • Odafeléjólmentek a dolgok, maguktólmentek a konverziók! • Visszafelémárnem!

  19. Kódelemzés • Megoldások: • char(i), ha i : integer, akkor i-t char-ra konvertáljuk. • static_cast<char>(i)(Később) • char ch = i;

  20. Kódelemzés #include<iostream> int main() { charch; std::cin >> std::ios_base::noskipws; while( std::cin >> ch ) { std::count << char('a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch); } return0; }

  21. Kódelemzés • Más lehetőség: • Saját toupper metódus írása! • Amit egyszer már megírtak, azt ne írjuk meg mégegyszer! • Beépített toupper metódus használata

  22. Kódelemzés • Írjunk olyan utility-t, ami úgy működik, mint egy unixparancs. • Ha nem adunk paramétert, akkor stdinput/outputot használja, ha adunk paramétert, akkor azt, mint fájlt akarja használni!

  23. Kódelemzés #include<iostream> intmain(intargc; char *argv[]) { ... }

  24. Kódelemzés #include<iostream> voidtoupper(std::istream&, std::ostream&); int main( intargc; char *argv[] ) { if ( argc < 2 ) { toupper(std::cin, std::cout); } }

  25. Kódelemzés • Akár van fájl, akár nincs, ugyanazt csinálom, ezzel megóvom magamat a dupla munkától! • az istream, ostream osztályoknak a copyconstruktoraprivate, hogy ne lehessen másolni, így mindig referencia szerint adom át öket paraméternek.

  26. Kódelemzés #include<fstream> #include<iostream> voidtoupper(std::istream&, std::ostream&); int main( intargc; char *argv[]) { if( argc < 2 ) { toupper(std::cin, std::cout); } else { // folyt. } return0; }

  27. Kódelemzés for( int i=1; i < argc; ++i ) { // Meg kell nyitni a fájlt! ifstreaminp(argv[i]); if ( !inp ) { std::cerr << "Can't open" << argv[i] << std::endl; } else { toupper(inp, std::cout); } }

  28. Kódelemzés • Kérdés: Kell-e close-tmondanom? • Amikor a zárójelet becsukom, akkor az ifstreamdestruktora meghívódik!

  29. Kódelemzés • Feladat:Számoljuk meg, hogy a bemeneten hány sor volt. (Sorvége-jel: ‘\n’)

  30. Kódelemzés #include<fstream> #include<iostream> voidlines(std::istream&, std::ostream&); intmain( intargc; char *argv[]) { if( argc < 2 ) { lines(std::cin, std::cout); } else { // folyt. } return0; }

  31. Kódelemzés for( int i=1; i < argc; ++i ) { ifstreaminp(argv[i]); if ( !inp ) { std::cerr << "Can't open" << argv[i] << std::endl; } else { lines(inp, std::cout); } }

  32. Kódelemzés • Egy adott karakter előfordulása egy egyszerű számlálás!

  33. Kódelemzés voidlines( std::istream&inp, std::ostream&outp ) { intcnt = 0; charprev = '\n'; charcurr; while ( std::cin.get(curr) ) { cnt = f(cnt, prev, curr); prev = curr; } }

  34. Kódelemzés int f( intcnt, charprev, charcurr ) // warning! { if( '\n' == prev ) { ++cnt; } returncnt; }

  35. Kódelemzés int f( intcnt, charprev, char) // így már nem! { if( '\n' == prev ) { ++cnt; } returncnt; }

  36. Kódelemzés • Javítás: voidlines( std::istream&inp, std::ostream&outp ) { intcnt = 0; charprev = '\n'; charcurr; while ( std::cin.get(curr) ) { cnt += '\n' == prev; prev = curr; } }

  37. Kódelemzés • Megoldás:#include<iostream>int main() {intls = 0;char c;while ( std::cin >> std::noskipws>> c) {if (c == ‘\n’) { ls += 1; } }std::cout<< ls << std::endl;return0;}

  38. Kódelemzés • Megoldás: más út#include<iostream>int main() {intls = 0;char c;while(std::cin >> std::noskipws>> c) {ls = (c == ‘\n’ ? ls + 1 : ls); }std::cout<< ls << std::endl;return0;}

  39. Kódelemzés • Kimenet:almaszilvactrl-Deredmény: 2almaszilva ctrl-Deredmény: 1

  40. Kódelemzés • Feladat:Írjuk át úgy a programot, hogy ne az ‘\n’ karaktereket keressük, mert az utóbbi esetben hibás a végrehajtás.

  41. Kódelemzés • Megoldás:int f ( charprev, intls) {returnprev == ‘\n’ ? ls + 1 : ls;}char c, prev;while ( std::cin >> std::noskipws>> c) {ls = f(prev, ls);prev = c;}

  42. Kódelemzés • Feladat:Szavak számának a számolása.alma (1) „ „ szilva (2) …

  43. Kódelemzés • Megoldás:int f (charprev, char c, intls) {return ( prev == ‘\n’ || prev == ‘\t’ || prev == ‘ ‘) && c != ‘\n’ && c != ‘\t’ && c != ‘ ’ ? ls + 1 : ls;}

  44. Kódelemzés • Megoldás: Más útboolisWS(char c) { …}

More Related