Kap 4: Mer om char och stränghantering

Relevanta dokument
C++ Lektion Tecken och teckenfält

Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p

TDIU01 - Programmering i C++, grundkurs

Programmering, grundkurs, 8.0 hp HI1024, HI1900 etc., Tentamen TEN1. Måndagen den 10 januari 2011,

TDIU01 (725G67) - Programmering i C++, grundkurs

1 Texthantering. 1.1 Typen char. Exempel, skriv ut alfabetet

Enkla datatyper minne

4 Sammansatta datatyper

Programmering i C++ EDAF hp. EDAF30 (Föreläsning 2) HT / 18

TDIU01 - Programmering i C++, grundkurs

OBS! All teori i detta och följande dokument kompletteras med genomgångar på lektionerna. Så det är viktigt att närvara och göra egna anteckningar.

En kort text om programmering i C.

C++ - En introduktion

LÖSNINGSFÖRSLAG TILL Tentamen i objektorienterad programmering i C++ I

Introduktionslaboration

Programmering i C. Vad är C? Målsättning. Litteratur. Jämförelse med Java. Exempel : Ett program som skriver ut texten Hello, world

FÖRSLAG TILL LÖSNING AV Tentamen i Objektorienterad programmering C++ I

Föreläsning 11. Strängar

Tecken & Strängar. Kapitel 7

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Övning från förra gången: readword

Användarhandledning Version 1.2

STRÄNGAR DATATYPEN. Om du vill baka in variabler eller escape-tecken måste du använda dubbla citattecken. strängar

Programmering, grundkurs, 8.0 hp HI1024, omtentamen, TEN1. Tisdagen den 7 juni 2011,

Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program

Grunderna i C++ T A. Skapad av Matz Johansson BergströmLIMY

Kap 6: Lista, stack och kö

Föreläsning 1: Momstabellen i C++

Övningsuppgifter till föreläsning 2 Variabler och uttryck

Föreläsning 2. Variabler, tilldelning och kodblock{} if-satsen Logiska operatorer Andra operatorer Att programmera

TDIU01 - Programmering i C++, grundkurs

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

C++ Slumptalsfunktioner + switch-satsen

PROGRAMMERING 2 GRUNDLÄGGANDE SEMANTIK 4

Tecken. char. char ch = A ; sizeof(char) = 1 byte (ej 16-bitars tecken som i Java) char namn[]= "Nils"; // längd = 5 bytes

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser

1 Funktioner och procedurell abstraktion

Strängar. Strängar (forts.)

Introduktionslaboration

C++ Funktioner 1. int summa( int a, int b) //funktionshuvud { return a+b; //funktionskropp } Värmdö Gymnasium Programmering B ++ Datainstitutionen

Klassdeklaration. Metoddeklaration. Parameteröverföring

TDDC76 - Programmering och Datastrukturer

PROGRAMMERING A C++ GOTOXY, TEXTCOLOR och GRAPHICS.h. Kompendium med lektionsanteckningar och övningsuppgifter. Stefan Sundin

Planering Programmering grundkurs HI1024 HT 2014

Programmering i C++ EDA623 Typer. EDA623 (Föreläsning 4) HT / 33

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Exempelduggan. Luffarschack. Koda spel

Visual Basic, en snabbgenomgång

Extramaterial till Matematik Y

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata.

TDIU01 - Programmering i C++, grundkurs

Datorövningar. Grunderna i C/C++

Vad har vi lärt oss så här långt Vad är en sträng? Strängkonstanter. Att skriva ut och läsa in strängar. Att arbeta med strängar.

Uppgifter till praktiska tentan, del A. (7 / 27)

Programmering i C, 7,5 hp

[] Arrayer = Indexerad variabel

Loopar och datatyper. Föreläsning 3

Programmeringsteknik med C och Matlab

Loopar och datatyper. Föreläsning 3

TDDC76 - Programmering och Datastrukturer

Tentamen i. för D1 m fl, även distanskursen. lördag 26 februari 2011

TENTAMEN MOM1 GRUNDLÄGGANDE PROGRAMMERINGSTEKNIK OCH

i LabVIEW. Några programmeringstekniska grundbegrepp

Datorlära 6. Arbeta med strängar Inmatning med tangentbordet Bygga ett program med inmatning, funktioner, osv

Programmering, grundkurs, 8.0 hp, Elektro, KTH, hösten 2010

Introduktion till programmering SMD180. Föreläsning 7: Strängar

Laboration 1 Introduktion till Visual Basic 6.0

1 Språket C Valet av språket C++ för kompendiet. 1.2 Språket. 1.3 Att programmera. 1.4 Hello World Börja programmera

Chapter 3: Using Classes and Objects

En villkorssats är den konstruktion som finns i C++ för att göra en selektion av två alternativa sekvenser. Formen för if satsen är

Agenda. Arrayer deklaration, åtkomst Makron Flerdimensionella arrayer Initiering Strängar Funktioner och arrayer. Övningar nu och då

Laboration 3 HI1024, Programmering, grundkurs, 8.0 hp

Inledande programmering med C# (1DV402) 85/2=42. OBS! Heltal 1 (13)

Code-Lite tutorial ( /RoJ)

2 Pekare och dynamiska variabler.

ÖREBRO UNIVERSITET. Lösningarna till tentamensuppgifterna sätts ut på kurssidan på nätet i dag kl 13.

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Strukturdiagram. Styra. Algoritmer. Val

TDIU01 - Programmering i C++, grundkurs

Objektorienterad Programmering (TDDC77)

Datorteknik 2 (AVR 2)

I Skapa Hej.java och skriv programmet. I Kompilera med javac Hej.java. I Rätta fel och repetera tills du lyckas kompilera ditt program

Nedan skapar vi klassen Person innehållande datamedlemmar för förnamn, efternamn, ålder, längd och vikt:

Tentamen ges för: Tentamensdatum: Tid:

Tentamen i. Programmering i språket C

Grundläggande C-programmering del 2 Pekare och Arrayer. Ulf Assarsson

Lösningar till uppgifterna sätts ut på kurssidan på nätet i dag kl Omtentamen i Programmering C, Fri, Kväll,

Introduktion till algoritmer - L0 - Grunder i C++ Matematikgymnasiet, Läsåret L0 - Grunder i C++

Python. Python är, som Scheme, ett interpreterat språk men det finns kompilatorer för Python.

Inledande programmering med C# (1DV402) Summera med while"-satsen

Inledande programmering med C# (1DV402) Ditt första C#-program med Visual Studio

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt

Att använda pekare i. C-kod

Programmeringsteknisk översiktskurs för yrkeshögskoleprogram

F4. programmeringsteknik och Matlab

KTH STH TENTAMEN. HI1024:TEN2 - Praktisk tentamen Tid: 8-13, den 18 februari 2012

Tentamen i. för D1 m fl, även distanskursen. lördag 28 maj 2011

732G Linköpings universitet 732G11. Johan Jernlås. Översikt. Repetition. Muddy cards. Slingor

Grundläggande programmering med C# 7,5 högskolepoäng

Transkript:

Kap 4: Mer om char och stränghantering Vi fortsätter med teckenvariabler, char, och skapar ett program, som skriver ut ASCII-tabellen. Sedan gör vi ett program, som skriver ut en char på slumpvis plats i fönstret, och använder funktionen setcolor(), som gör det möjligt att använda färger i console-programmering. I det här kapitlet gör vi också ett program, som visar hur textsträngar är uppbyggda och hur de deklareras och matas in från tangentbordet. Vi ska också kopiera och sätta samman strängvariabler till nya strängar. 1. ASCII-tabellens tecken Skapa en ny mapp med namnet Kap 04, där alla projekt i det här kapitlet sparas. Förutom int, som lagrar heltalsvariabler, och double och float, som lagrar flyttal (decimaltal), har vi också använt typen char tidigare. En char-variabel lagrar ett tecken. Tecknen anges i teckenuppsättningen ASCII, som betyder American Standard Code for Information Interchange. På svenska: amerikansk standardkod för informationsutbyte. Teckenuppsättningen innehåller 256 tecken, 0 255, eftersom det går att skriva 256 olika heltal med minnesenheten 1 byte. Tabellen innehåller bokstäver, siffror och specialtecken. Den vanligaste uppsättningen visar i Appendix A längst bak i boken. Tecken 129 255 kan dock variera en del i olika versioner. Stora bokstäverna A - Z (versaler i engelska språket) har nummer 65 90 medan de små bokstäverna a z har nummer 97 122. Det innebär att om 32 adderas till versalens nummer erhålls det gemena tecknet. Eftersom A har nummer 65 har a nummer 65 + 32 = 97. B har nummer 66 och b nummer 98 eftersom 66 + 32 = 98. Detta gäller dock inte Å, Ä och Ö samt å, ä och ö, som inte har nummer efter den här principen. En char lagrar endast det heltal, som svarar mot numret i tabellen. Kompilatorn översätter sedan numret till symbolen. Det program vi ska skapa i det här avsnittet ska skriva ut tecken 32 255 i ASCI-tabellen. Vi börjar med tecken 32, som är blanktecknet, eftersom tecken 0-31 är styrtecken, som radslut, nyrad-tecken etc. En del av tecknen 0 32 har inte längre någon större användning i console-program men finns kvar av kompatibilitetsskäl. Lägg in följande kod i projektets cpp-fil: // Ex01_04. Program som skriver ut ASCII-tecknen 32 255 #include <iostream> #include <conio.h> using namespace std; #include <svtecken.h> int main() teckenbyt(); for (int j=32; j<255; j++) if (j<100) cout << ; cout << j << : << (char)j << ; cout << \n\n ; cout << Tryck tangent ; getch(); return 0; 53

Här används en for-sats för att skriva ut tecknen. För att det ska bli tilltalande, se snyggt ut, används en if-sats, för att skriva mellanslag före alla nummer under 100. Vissa av tecknen under 32 är viktiga, exempelvis tecken nr 13 som är nyrad-tecknet. Tecken nr 7 är också ett användbart tecken, eftersom det ger ett pip i datorns inbyggda högtalare. Komplettera programmet med följande rad före slutraderna: cout << (char)7; Kör programmet på nytt. Nu hörs ett pip då uppmaningen att trycka tangent ges. 2. Utskrift av stjärnor Uppgift 1, Uppgift 2 I det här avsnittet ska vi skriva ett program som skriver ut tecken 42, *, på slumpmässig plats på skärmen med hjälp av gotoxy(). Skapa ett nytt projekt, Ex02_04, och lägg in följande kod i cppfilen: // Ex02_04. Program som skriver en stjärna på slumpvis plats #include <iostream> #include <conio+.h> #include <time.h> // Behövs endast i Visual using namespace std; #include <svtecken.h> int main() teckenbyt(); char ch='s'; int kol, rad; srand(time(0)); gotoxy(1,24); cout << Tryck S för stjärna. Sluta - tryck annat tecken: ; ch=getch(); while (ch=='s' ch=='s') kol=rand()%80+1; rad=rand()%22+1; gotoxy(kol,rad); cout << '*'; gotoxy(1,24); cout << Tryck S för stjärna. Sluta - tryck annat tecken: ; ch=getch(); cout << \n\n ; return 0; Här används read ahead-teknik och när ett S eller s trycks slumpas en kolumn från 1 till 80 och en rad från 1 till 22. En stjärna skrivs ut. Vi stoppar vid 22 eftersom inte texten längst ner i fönstret ska skrivas över. Om annan tangent trycks bryts while-loopen och programmet avslutas. Som 54

du ser tillåter while-villkoret litet eller stort s för brytning. Båda tecknen går bra. Vi ska använda funktionen setcolor() som finns i conio+.h. Lägg till deklarationen av color och två rader inuti while-kroppen: int color; while (ch=='s' ch=='s') kol=rand()%80+1; rad=rand()%22+1; color=rand()%16; setcolor(color); gotoxy(kol,rad); cout << '*'; setcolor(7); gotoxy(1,24); cout << Tryck S för stjärna. Sluta - tryck annat tecken: ; ch=getch(); Kör programmet. Bilden ovan visar hur console-fönstret kan se ut efter att stjärnor har slumpats ett tag. Följande 16 färger kan väljas med setcolor(): Heltal Namn Färg Heltal Namn Färg 0: BLACK Svart 8: DARKGRAY Mörkgrå 1: BLUE Blå 9: LIGHTBLUE Ljusblå 2. GREEN Grön 10: LIGHTGREEN Ljusgrön 3: CYAN Blågrön 11: LIGHTCYAN Ljusblågrön 4: RED Röd 12: LIGHTRED Ljusröd 5: MAGENTA Violett 13: LIGHTMAGENTA Ljusviolett 6: BROWN Brun 14: YELLOW Gul 7: LIGHTGRAY Ljusgrå 15: WHITE Vitt 55

Först deklareras int color, som ger olika textfärger som värde i setcolor(), som finns i conio+.h. Funktion bestämmer textfärgen och färgade stjärnor skrivs ut. I parentesen ska ett heltal från 0 och högst 15 skrivas. Alternativt kan konstanterna, som anges med namnen i tabellen användas. Eftersom den ursprungliga textfärgen är 7 (LIGHTGRAY) måste den återställas innan cout-satsen uppmanar användaren att trycka nytt tecken. Vi ändrar programmet så att stjärnor skrivs ut i hela fönstret tills en tangent trycks. Byt ut koden i main() mot följande: teckenbyt(); char ch='s'; int kol, rad, color; srand(time(0)); while (kbhit()==false)//ch=='s' ch=='s') kol=rand()%80+1; rad=rand()%25+1; color=rand()%16; if (kol==80&&rad==25) continue; setcolor(color); gotoxy(kol,rad); cout << '*'; cout << \n\n ; return 0; Här används funktionen kbhit(), som låter while-satsen pågå tills en tangent trycks. Eftersom utskrift av stjärnor i sista skärmpositionen (80,25) medför scrollning finns en if-sats i koden, som i så fall avbryter loopen så att nya värden kan slumpas. Utskrift av stjärnor sker alltså inte i hela fönstret, eftersom sista positionen aldrig används. 3. Teckensträngar Om man använder många teckenvariabler av typ char efter varandra fås en teckensträng. Vi ska börja med att skriva ut några char efter varandra. Skapa ett nytt projekt och lägg in följande kod i cpp-filen: // Ex03_04. Program som deklarerar och skriver textsträngar #include <iostream> #include <conio.h> using namespace std; #include <svtecken.h> int main() teckenbyt(); char ch1='c', ch2='+', ch3='+'; Uppgift 3 cout << \njag gillat att programmera i << ch1 << ch2 << ch3 << '.'; 56

cout << \n\n\n ; cout << Tryck tangent ; getch(); return 0; Kör programmet. De tre deklarerade tecknen, som också initieras vid deklarationen, skrivs ut. Vi kan deklarera en teckensträng med koden: char str[]= C++ ; Ett fält bestående av tre tecken deklareras och ges namnet str. Att str är ett fält, dvs ett antal tecken i rad, anges med hakparenteserna. Mellan dessa kan antalet tecken, som fältet ska bestå av, skrivas. I det här fallet behövs detta inte, eftersom antalet framgår av initieringen: str[]= C++ ; Bygg ut programmet ovan med följande kod före slutraderna: char str[4]= C++ ; cout << \n\njag gillar att programmera i << str << '.'; Kör programmet igen. Som du ser blir resultatet det samma. Fältet skrivs ut som en enhet. Istället för ordet fält används ofta den engelska beteckningen array och man säger då ofta på svenska arrayen. Observera att minnesutrymme har reserverats av programmet för fyra tecken eftersom tecknen avslutas med nolltecknet, dvs tecknet med ASCII-kod 1. Detta skrivs här \0 och så här ser str ut: C + + \0 Strängvariabeln består av fyra tecken om det avslutande nolltecknet också räknas. Det går inte att utöka antalet tecken till fler än som deklarerats från början. Efter de tre tecknen följer det avslutande nolltecknet. Vi bygger ut programmet och deklarerar ytterligare en sträng: cout << \n\nsträngen består av följande tecken: << str[0] << ' ' << str[1] << ' ' << str[2]; cout << \n\ndet fjärde tecken är nolltecknet. ; Kör programmet. Som du ser kan varje tecken plockas fram med indexet i klammern. Genom att använda en heltalsvariabel kan man bekvämt plocka fram vilket tecken som helst i en sträng. Genom att tilldela platsen ett nytt tecken kan strängen också ändras. I koden nedan går loopen igenom strängen C++ och byter alla plus mot minus genom att använda en if-sats. char[] str= C++ ; for (int j=0; j<3; j++) if (str[j]=='+') str[j]='-'; Observera de dubbla lika med-tecken i villkoret och det enkla i tilldelningen. Vi deklarerar ytterligare än strängvariabel, str2, med följande tillägg som placeras efter föregående kod: char str2[9]= språket ; cout << \n\njag gillat att programmera i << str2 << str; Kör programmet på nytt. Här deklareras en sträng som är åtta tecken lång. Det åttonde tecknet utgörs av mellanslaget på 57

slutet. Längden skrivs i hakparentesen och där anges 9 eftersom det avslutande nolltecknet upptar en plats det också. Utskrift görs med cout som vanligt, men förutsättningen för att det ska fungera är, att strängen avslutas med nolltecken. Lägg till följande kod efter den föregående och före slutraderna: char str3[16]= programspråket ; cout << \n\njag gillat att programmera i << str3 << str <<. ; Innehållet i en sträng kan bytas mot nytt innehåll, men observera att det inte fungerar att lägga en ny sträng i str2 genom att skriva: str3= språket C++. ; Istället används funktionen strcpy(), som kopierar strängen och placerar den i den andra strängen. Vi ska studera funktionen strcpy() och andra strängfunktionerna mer längre fram i kapitlet men bygger nu ut programmet med följande kod: strcpy(str2, språket C++. ); cout << \n\njag gillar att programmera i << str2; Kör programmet och observera att texten i str2 nu har bytts mot språket C++. Om innehållet i en sträng ska bytas används funktionen strcpy(). Uppgift 4, Uppgift 5 4. Inmatning av strängar Vi ska mata in textsträngar från tangentbordet i det här avsnittet. Skapa ett projekt, Ex04_04, och lägg in följande kod i cpp-filen: // Ex04_04. Inmatning av textsträngar #include <iostream> #include <conio.h> using namespace std; #include <svtecken.h> int main() teckenbyt(); char str[35]; cout << \nmata in en textsträng: ; cin >> str; cout << \ndu matade in strängen: << str; cout << \n\n\n ; cout << Tryck tangent ; getch(); return 0; Kör programmet. Prova att mata in strängen: Jag gillar att programmera i C++ Som du märker går det inget vidare. Det är endast första ordet som lagras i str. Inläsningen 58

fungerar endast fram till mellanslaget, som är ett vitt tecken. Ett annat vitt tecken är returtryckningstecknet 13. När inläsningen stöter på ett sådant tecken avbryts den. Byt ut mittraderna mot följande: char str[35]; cout << \nmata in en textsträng: ; cin.getline(str, sizeof(str)); cout << \ndu matade in strängen: << str; Kör programmet igen. Mata in strängen: Jag gillar att programmera i C++ och konstatera att det nu fungerar utmärkt. För att visa de problem, som kan uppkomma, ska vi läsa in en sträng, som är för lång, och sedan fortsätta att läsa in ännu en sträng. Lägg in följande efter den föregående koden: cout << \n\n\nmata in en ny textsträng: ; cin.getline(str, sizeof(str)); cout << \ndu matade in strängen: << str; Kör programmet och mata in strängen: Jag gillar verkligen att programmera i C++ Nu fungerar det inte eftersom strängen är för lång. Den är längre än 34 tecken. Men sedan blir det verkligen kris, som du ser. Inmatning av nästa sträng misslyckas helt. Det första felet får alltså följdverkningar. Byt ut mittraderna mot dessa istället: char str[35]; cout << \nmata in en textsträng: ; cin.get(str, sizeof(str)); cin.ignore(1000,'\n'); cout << \ndu matade in strängen: << str; cout << \n\n\nmata in en ny textsträng: ; cin.get(str, sizeof(str)); cin.ignore(1000,'\n'); cout << \ndu matade in strängen: << str; Kör programmet och mata först in Jag gillar verkligen att programmera i C++ och i andra inmatningen den kortare strängen Jag gillar att programmera i C++. Andra gången fungerar nu eftersom det inte blir några följdverkningar av att strängen första gången var för lång. Vid inmatning av strängar från tangentbordet bör cin.get() användas istället för funktionen cin.getline(). Dessutom bör cin.get() följas av cin.ignore(1000,'\n'); Inuti parentesen i cin.get() anges namnet på den sträng, som ska lagra texten, och därefter strängens längd. Lämpligt är att använda sizeof() enligt koden i exemplet. Returtryckningstecknet \n finns då kvar i inmatningsbufferten och möjliggör användning av cin.ignore() för att rensa bufferten. Vanligt är att ange 1000,'\n' i parentesen. Det betyder att högst 1000 tecken fram t o m returtryckningstecknet kommer att hoppas över vid nästa inläsning. Eftersom bufferten sällan innehåller så många tecken fungerar det alltid i praktiken. Bufferten töms och är redo för ny inmatning. Men finns inget \n i bufferten sker heller ingen tömning. Funktionen cin.ignore() kan inte användas efter cin.getline(), eftersom även tecknet \n placeras i strängvariabeln och alltså inte ligger kvar i inmatningsbufferten. Funktionen sizeof() ger storleken på en variabel. För att ta reda på hur många tecken, som får plats i en sträng, subtraherar man 1 från det värde som sizeof() ger. Men naturligtvis är inte det värde som sizeof() ger detsamma som strängens verkliga längd. För att enkelt ta reda på strängens längd används funktionen strlen(). 59

Lägg in följande kod efter den föregående för att prova: cout << \n\n\nden sist inmatade strängen är << strlen(str) << tecken lång men plats finns för << sizeof(str)-1 << tecken. ; Kör programmet. Nu skrivs strängens längd ut med strlen(), och sizeof() används för att skriva ut hur stort utrymme som finns i strängen. Uppgift 6 5. Kopiering och sammankoppling av strängar För att kopiera en sträng till en annan används funktionen strcpy(), som vi redan använt oss av. Om endast ett visst antal tecken ska kopieras används istället strncpy(), som kopierar det antal tecken, som anges, till den mottagande strängen. Vi ger exempel i nedanstående kod där också funktionen strcat() används. Med strcat() sätter man samman strängar, två i taget. Lägg in följande kod i cpp-filen: // Ex05_04. Kopiering och sammansättning av strängar #include <iostream> #include <conio.h> using namespace std; #include <svtecken.h> int main() teckenbyt(); char str[]= Kaj-Göran är förnamnet., fornamn[10], efternamn[]= Klang, namn[20]= ; cout << endl << str << \n\nefternamn: << efternamn; strncpy(fornamn, str, 9); fornamn[9]='\0'; cout << \n\nförnamnet kopierat med strncpy: << fornamn; strcat(namn, fornamn); strcat(namn, ); strcat(namn, efternamn); cout << \n\nhela namnet sammansatt med strcat: << namn; cout << \n\n\n ; cout << Tryck tangent ; getch(); return 0; Kör programmet och studera koden. Förnamnet kopieras till fornamn med strncpy(), som kopierar över de nio första tecknen i str. Men fornamn måste avslutas med ett nolltecken. Det sker genom att skriva in ett nolltecken som tecken nr 10. Tecknen i strängar numreras alltså från 0 och uppåt: 0, 1, 2 etc. Det första tecknet i fornamn är K, som är tecken 0, det andra är a, som är tecken 1 etc. Strängen namn sätts sedan 60

samman av fornamn, ett tomtecken (mellanslag) och efternamn. Det sker genom att variabeln namn, som är tom från början, först sätts samman med fornamn med strcat(). Sedan sätts namn ihop med ett tomtecken och slutligen kopplas även efternamn till. Strängar måste sättas samman med strcat() två i taget. Finns behov kan strncat() användas istället. Då kan ett visst antal tecken från en sträng adderas till en annan sträng, liksom vid kopiering med strncpy(). För att få reda på hur lång en sträng är används som vi berättat tidigare - funktionen strlen(). Lägg till följande kod: cout << \n\nnamnets längd: << strlen(namn) << tecken ; Kör programmet. Som du ser är strlen() väldigt behändig att använda. Tecknen i en sträng kommer man åt med indexering. Vi avslutar detta avsnitt med att ta fram tecknen i strängen namn, ett efter ett, och skriver ut dem. Lägg in följande kod efter den föregående: cout << \n\ntecknen i namnet: ; for (int j=0; j<strlen(namn); j++) cout << ' ' << namn[j]; Kör programmet och se hur fint det fungerar. I Builder ges en varning: Comparing signed and unsigned values. Den varningen försvinner om konvertering till int görs före strlen(): cout << \n\ntecknen i namnet: ; for (int j=0; j<(int)strlen(namn); j++) cout << ' ' << namn[j]; Naturligtvis kan man strunta i varningen, men de utgör på något sätt en skönhetsfläck, som det känns skönt att ta bort. Uppgift 7, Uppgift 8 6. Jämförelse av strängar med strcmp() eller stricmp() Strängar kan ordnas i storleksordning genom att använda ASCII-koden för de olika tecknen som hjälp. Stängen Arne är mindre än Bertil eftersom A kommer före B i alfabetet. Arne är också mindre än arne eftersom det gemena a:et har ASCII-nummer 97, som kommer efter numret för A som är 65. Adolf är större än Adam eftersom o kommer efter (är större än) a i alfabetet. För att göra dessa jämförelser används funktionen strcmp(), som ger talet noll, om strängarna är lika och annars talet 1 eller -1. Se följande exempel: strcmp( Arne, Bertil ) ger talet 1, eftersom Arne är mindre än Bertil. strcmp( Bertil, Arne ) ger däremot talet 1, eftersom Bertil är större än Arne. strcmp( Arne, Arne ) ger talet 0 som resultat, eftersom två lika strängar jämförs. Skapa ett nytt projekt, Ex06_04, och lägg in följande kod i cpp-filen, Ex06.cpp: // Ex06_04. Ordning av strängar med strcmp() #include <iostream> 61

#include <conio.h> using namespace std; #include <svtecken.h> int main() teckenbyt(); char namn1[20]=, namn2[20], temp[20]; while (strcmp(namn1, )!=0) cout << \nmata in ett förnamn (Sluta - tryck enbart retur): ; cin.get(namn1,sizeof(namn1)).ignore(1000,'\n'); if (strcmp(namn1, )==0) break; cout << \nmata in ett förnamn till: ; cin.get(namn2,sizeof(namn2)).ignore(1000,'\n'); if (strcmp(namn1,namn2)>0) strcpy(temp,namn1); strcpy(namn1,namn2); strcpy(namn2,temp); if (strcmp(namn1,namn2)==0) cout << \ndet är samma namn två gånger\n\n ; else cout << \ni bokstavsordning: << namn1 << << namn2 << \n\n ; cout << \n ; return 0; Här används strcmp() för att avgöra vilket namn, som kommer först i bokstavsordning. Men observera att strcmp() inte ger rätt resultat med de svenska tecknen Å, Ä och Ö och å, ä och ö. Funktionen är gjord för tecknen i ASCII-koden. Exemplet visar också hur den tomma strängen, som fås genom tryck av enbart returtangenten, kan identifieras med strcmp(). I programmet avbryts inmatningen med tryck på enbart <Enter>. Det är ett enkelt och snyggt sätt att bryta while-loopen. Matas samma namn in båda gångerna skrivs texten Det är samma namn två gånger ut. Men om Arne och arne matas in ger jämförelsen att arne > Arne. Om man inte vill att versaler och gemener ska ha betydelse kan istället funktionen stricmp() användas. Funktionen stricmp() fungerar precis som strcmp(), men gör inte skillnad mellan stora och små bokstäver. Ändra i koden enligt nedan:... kod som tidigare cin.get(namn2,sizeof(namn2)).ignore(1000,'\n'); if (stricmp(namn1,namn2)>0) strcpy(temp,namn1); strcpy(namn1,namn2); strcpy(namn2,temp); if (stricmp(namn1,namn2)==0) cout << \ndet är samma namn två gånger\n\n ; else kod som tidigare... 62

Kör programmet och mata in samma namn ena gången med gemener, andra gånger med versaler. Som du ser gör inte stricmp() skillnad på dessa. Matas Arne och arne in säger programmet att det är samma namn, vilket det ju också är! Uppgift 9, Uppgift 10 Sammanfattning av kapitel 4: Vi har: arbetat vidare med teckenvariabler och skrivit ut ASCII-tabellen visat hur utskrift av tecken kan slumpas i console-fönstret visat hur textfärg kan ändras med funktionen setcolor() deklarerat och initierat textsträngar som är fält av tecken lärt oss att tecknen i en sträng kan läsas och ändras med hjälp av indexering lärt oss mata in textsträngar och att rensa bufferten efter inmatning visat hur strängar kopieras och sätts ihop använt strcmp() och stricmp() för att ordna strängar i bokstavsordning 63

64

Uppgifter: 1. Skriv ett program, som läser in tre tecken med getch() eller getche(), och sedan skriver ut tecknen efter varandra. 2. Skriv ett program där användaren trycker en liten (gemen) bokstav. Programmet ska sedan omvandla och skriva ut tecknet som stor bokstav (versal) istället. 3. Skriv ett program som slumpar två gemena bokstäver (a z) och sedan skriver ut dem i bokstavsordning genom att använda ASCII-tecknen. Programmet ska använda olika färger vid utskriften. Exempelvis kan tecknen skrivas med olika färger. 4. Deklarera fyra strängvariabler, flod1, flod2, flod3 och flod4. Ge dem värdena Lagan, Nissan och Ätran och Viskan. Använd variablerna för att skriva ut texten: Hallands floder heter Lagan, Nissan, Ätran och Viskan. 5. Skriv ett program där användaren ska mata in en sträng med ett eller flera a:n. Sedan ska alla bokstäver a bytas mot b. Slutligen ska programmet skriva ut den ändrade strängen. Ledning: För att avgöra strängens längd kan antalet tecken räknas. Tecknen i strängen är skiljt från nolltecknet utom på slutet. 6. Deklarera en strängvariabeln och låt användaren mata in en sträng. Ange i ledtexten att strängen får vara högst 15 tecken lång. Programmet ska sedan skriva ut strängen snett ned åt höger ungefär som visas nedan. Om strängen PROGRAMMERING matas in, ska utskriften bli: P R O G R A M M E R I N G 65

7. Skriv ett program där användaren matar in en textsträng, högst 20 tecken lång. Programmet ska sedan ändra strängen så att den istället lagras baklänges. Vid utskrift skrivs alltså texten baklänges. 8. Skriv ett program som frågar efter enhet, mappnamn, filnamn. Till slut ska programmet skriva ut sökvägen. I nedanstående exempel är det som matas in understruket: Mata in enhet: C Mata in mappnamn: Kap 4 Mata in filnamn: Min_fil Mata in suffix: cpp Sökväg: C:\Kap 4\Min_fil.cpp Obs: Tecknet \ (omvänt snedstreck, backslash) måste skrivas dubbelt eftersom det är ett s k excape-tecken. Ett escape-tecken förändrar betydelsen av det tecken som följer efter. Normalt betyder ju n bokstaven n, men om det föregås av escapetecknet \ (\n) betyder det ny rad. Ska accent och citattecken skrivas i en sträng måste dessa tecken också föregås av omvänt snedstreck \. 9. Ett palindrom är ett ord, som blir samma, om man läser från vänster till höger eller baklänges. Exempel är apa, girig och nitalarbralatin (ni talar bra latin). Skriv ett program där ett ord ska matas in, och programmet sedan kan avgöra, om det är fråga om ett palindrom eller inte. Gör programmet upprepningsbart. Om en tom sträng matas in, ska programmet avslutas. 10. Skriv ett program där tecknet X skrivs mitt på skärmen. X:et ska kunna styras med hjälp av piltangenterna och det ska inte vara möjligt att röra X:et utanför fönstret. Det innebär att kolumnen högst ska kunna vara 80 och raden högst 25. Styrtangenter, som piltangenterna, genererar två ASCII-koder varav det första är noll. Använd alltså getch() två gånger. Programmet ska avslutas med tryck på <Escape>. 66