C++-manual | ||
---|---|---|
Förutgående | Appendix A. C-strängar | Nästa |
Här börjar C-strängar skilja sig från string. Varken tilldelning eller jämförelse med C-strängar är speciellt intuitiv, och man behöver för det mesta ta extra funktioner till hjälp.
Strängar kan inte direkt tilldelas. Eftersom det är frågan om vektorer och således även pekare är det enda som händer att pekarens värde kopieras och båda pekarna refererar ännu till samma minnesområde och sträng. Exempel:
#include <iostream> int main () { char Hello1[] = "Hello 1!"; char * Hello2; // skriv ut Hello1 cout << "Hello1 = '" << Hello1 << "'" << endl << endl; // tilldelning Hello2 = Hello1; // manipulera Hello2 Hello2 [6] = '2'; // skriv ut Hello1 och Hello2 cout << "Hello1 = '" << Hello1 << "'" << endl; cout << "Hello2 = '" << Hello2 << "'" << endl; } |
Strängen Hello2 blir inte en kopia, utan den pekar ännu på samma omtåde som Hello1. Följdaktligen påverkar manipuleringen av ett tecken i Hello2 även Hello1, vilket visas i utskriften. Där har teckent 1 bytts till 2 i båda strängarna. Vi har gjort en grund kopia (shallow copy) av den ursprungliga strängen. I grunda kopior påverkas originalet. Vad vi egentligen för det mesta vill åstadkomma är djupa kopior (deep copy) där hela strängens värde kopieras. Detta kan åstadkommas med t.ex följande kod:
char Hello1[5] = "Hej!"; char Hello2[5]; // utför kopieringen teckenvis for ( int Index = 0; Index < 5; Index++ ) Hello2[Index] = Hello1[Index]; |
Notera att här har vi färdigt allokerat minne för Hello2. Man måste alltid försäkra sig om att det finns allokerat minne dit man ämnar kopiera en sträng. Mera om kopiering i avsnittet Kopiering av strängar.
Jämförelser kan inte direkt utföras med operatorn == eller !=. Inte heller kan man utföra alfabetisk jämförelse med <, <=, >= eller >. Vi måste jämföra teckenvis. Om de jämförda strängarna är lika långa och innehåller exakt samma tecken är de lika. Vi kan skriva en egen jämförelsefunktion på följande sätt:
#include <iostream> bool compare (const char * S1, const char * S2) { int Index1 = 0; int Index2 = 0; // säkerhet if ( ! S1 || ! S2 ) // någondera (eller båda) strängarna odefinierade return false; while ( S1[Index1] != '\0' && S2[Index2] != '\0' ) { // är tecknen ännu lika? if ( S1[Index1++] != S2[Index2++] ) // nope, så strängarna är olika return false; } // strängarna är lika return true; } int main () { char * S1 = "Hej!"; char * S2 = "Hello world, this is main() calling"; char * S3 = "Hello world, this is main() calling"; // jämförelse if ( compare ( S1, S2 ) ) cout << "S1 och S2 är lika" << endl; else cout << "S1 och S2 är olika" << endl; if ( compare ( S2, S3 ) ) cout << "S2 och S3 är lika" << endl; else cout << "S2 och S3 är olika" << endl; } |
Körning ger följande resultat:
% ./CStringCompare1 S1 och S2 är olika S2 och S3 är lika % |
Jämförelsen är alltså ganska trivial till sin natur att implementera, men det finns en färdig funktion som man kan använda, som är en del mångsidigare. Den heter strcmp() och ser allmänt ut på följande sätt:
#include <string.h> int strcmp(const char * S1, const char * S2); |
Den finns definierad i <string.h>. Returvärdet är en aning speciellt, och är:
< 0 om S1 är mindre än S2.
== 0 om S1 är lika med S2.
> 0 om S1 är större än S2.
Man kan på så sätt enkelt utföra alfabetisk jämförelse mellan två strängar. Funktionen antar att båda strängarna är korrekt terminerade av '\0'. Vi kan då skriva om vårt program från ovan på följande sätt:
#include <iostream> #include <string.h> int main () { char * S1 = "Hej!"; char * S2 = "Hello world, this is main() calling"; char * S3 = "Hello world, this is main() calling"; // jämförelse if ( strcmp ( S1, S2 ) == 0 ) cout << "S1 och S2 är lika" << endl; else cout << "S1 och S2 är olika" << endl; if ( strcmp ( S2, S3 ) == 0 ) cout << "S2 och S3 är lika" << endl; else cout << "S2 och S3 är olika" << endl; } |
Vi är här endast intresserade av om de är lika, inte hur de förhåller sig alfabetiskt till varandra.
En varient på funktionen ovan tar som ett tredje argument antalet tecken som maximalt skall jämföras. Den heter strncmp(). Vi kan modifiera programmet ovan en aning:
#include <iostream> #include <string.h> int main () { char * S1 = "Hello world"; char * S2 = "Hello"; // jämförelse if ( strncmp ( S1, S2, 5 ) == 0 ) cout << "S1 och S2 är lika" << endl; else cout << "S1 och S2 är olika" << endl; } |
Körning ger nu resultatet:
% ./CStringCompare2 S1 och S2 är lika % |
Eftersom vi jämförde endast fem tecken av de båda strängarna gav strncmp() svaret att de är lika. Med normala strcmp() eller ett längre intervall till strcmp() hade strängarna varit olika.
Förutgående | Hem | Nästa |
Hur C-strängar fungerar | Upp | Längden av strängar |