Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'Tekststrenge
27.  Tekststrenge i C

Denne lektionen er om tekststrenge, som både har berøringspunkter med arrays og pointers. Programmering med tekststrenge er vigtig i enhver form for tekstbehandling. Lektionen udspænder kapitel 27 - kapitel 31.

27.1 Strenge og tekststrenge27.5 Ændringer af tekststrenge
27.2 Tekststrenge og arrays27.6 Tekststrenge i forhold til tegn
27.3 Initialisering af tekststrenge27.7 Den tomme streng og NULL
27.4 Tekststrenge og pointere
 

27.1.  Strenge og tekststrenge
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Vi starter forholdsvis generelt med at definere strenge og tekststrenge.

En streng er en sekvens af data af samme type

En tekststreng er en streng af datatypen tegn

I de fleste programmeringssprog noteres tekststrenge ved brug af dobbelte anførselstegn. Dermed adskiller strenge sig fra tegn (se afsnit 16.3) der i mange sprog noteres ved enkelte anførselstegn. Se endvidere afsnit 27.6.

  • Almen notation for tekststrenge:

    • "En tekststreng"

  • Den tomme streng

    • Strengen der ikke indeholder data

    • Strengen af længde 0 - den kortest mulige streng

    • Den tomme tekststreng noteres naturligt som ""

 

27.2.  Tekststrenge og arrays
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Efter den korte, generelle introduktion til tekststrenge i afsnit 27.1 ser vi nu konkret på tekststrenge i C. Den vigtigste detalje er konventionen om, at der skal bruges et særligt tegn, nultegnet, for at afslutte en tekststreng. Nultegnet er det tegn i ASCII alfabetet (afsnit 16.1 og program 16.2) som har talværdien 0. Det er med andre ord det første tegn i tabellen.

En tekststreng i C er et nulafsluttet array med elementtypen char.

I figur 27.1 herunder ser vi tekststrengen "Aalborg", som det repræsenteres i et array. Læg mærke til tegnet i position 7: nul tegnet. Uden dette tegn ved vi ikke hvor tekststrengen afsluttes i lageret.

Figur 27.1    En illustration af en nulafsluttet tekststreng i C

  • Det afsluttende nultegn kaldes en sentinel

    • Oversættes direkte som en 'vagt'

    • Eksplicit markering af afslutningen af tekststrengen

    • Som et alternativt kunne vi holde styr på den aktuelle længde af tekststrengen

Herunder, i figur 27.2 viser vi tekststrengen "Aalborg" placeret midt i et array. Med en char pointer som peger på celle 2 i tabellen har vi stadig fat i "Aalborg".

Figur 27.2    En tekststreng som er placeret 'i midten' af et array of char

En tekststreng i C skal ikke nødvendigvis udfylde hele det omkringliggende array

 

27.3.  Initialisering af tekststrenge
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Der er flere forskellige måder at initialisere en tekststreng. Herunder, i program 27.1 viser vi essentielt tre forskellige. Bemærk at de tre første initialiseringer foregår som en del af erklæringen af hhv. str_1, str_2 og str_3.

Den røde måde benytter manifest array notation, som blev diskuteret i program 21.3 i afsnit 21.2.

Den blå og den lilla måde er overfladisk set sammenfaldende. Her benytter vi en strengkonstant i dobbeltquotes, som diskuteret i afsnit 27.1. Den blå måde bruger en array variabel, og den lilla en pointervariabel. I den blå måde, hvor vi initialiserer str_2 sker der en implicit kopiering af tegn fra tekststrengen "Aalborg" over i arrayet. I afsnit 27.5 diskuterer vi nogle vigtige forskelle mellem den blå og lilla form, hvad angår mulighederne for efterfølgende ændringer (mutation) af tegn i strengene.

Med den brune måde indsætter vi enkelttegn i et array pr. assignment.

Læg mærke til at den røde og brune måde kræver eksplicit indsættelse af nultegnet. Nultegnet skal ikke indsættes eller noteres eksplicit, når vi bruger strengkonstanter.

1
2
3
4
5
6
7
8
9
10
  char str_1[] = {'A', 'a', 'l', 'b', 'o', 'r', 'g', '\0'};

  char str_2[] = "Aalborg";

  char *str_3 = "Aalborg";

  char str_4[8];
  str_4[0] = 'A';  str_4[1] = 'a';  str_4[2] = 'l';  
  str_4[3] = 'b';  str_4[4] = 'o';  str_4[5] = 'r';  
  str_4[6] = 'g';  str_4[7] = '\0';   
Program 27.1    Forskellige initialiseringer af tekststrenge.

Vi skriver endnu et program, som ligner program 27.1. I program program 27.2 gennemfører vi assignments i stedet for initialiseringer. De første to assignments, på det røde og blå sted, er ulovlige. Den første bruger en initializer, som kun må anvendes i erklæringer. Den anden forsøger at assigne en tekstreng (som er konstant tekststreng i programmet) til en array variabel str_2. Dette er ulovlig, idet str_2 er konstant (kan ikke assignes). Ydermere vil der ikke - bag ryggen på programmøren - blive kopieret tegn fra den konstante tekststreng til str_2 arrayet. Det lilla assignment af str_3 er lovlig, men bemærk, at der er tale om en pointer assignment. De brune assignments til str_4 elementerne er naturligvis også OK.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>

int main(void) {

  char str_1[8], str_2[8], *str_3, str_4[8];

  /* Ulovlig brug af initializer */
  str_1 = {'A', 'a', 'l', 'b', 'o', 'r', 'g', '\0'};

  /* Ulovlig assignment til array navn. Implicit kopiering finder ikke sted */
  str_2 = "Aalborg";

  /* Alternativ: kopier tegnene selv */
  strcpy(str_2, "Aalborg");

  /* Pointer assignment - OK */
  str_3 = "Aalborg";

  /* Tegnvis assignment - OK */
  str_4[0] = 'A';  str_4[1] = 'a';  str_4[2] = 'l';  
  str_4[3] = 'b';  str_4[4] = 'o';  str_4[5] = 'r';  
  str_4[6] = 'g';  str_4[7] = '\0';     

  printf("%s\n%s\n%s\n%s\n", str_1, str_2, str_3, str_4);
  
  return 0;
}
Program 27.2    Tilsvarende forsøg på assignments til de fire tekststrenge.

 

27.4.  Tekststrenge og pointere
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Vi skal nu se på forholdet mellem tekststrenge og pointere. I bund og grund er dette forhold afledt af at en tekststreng er et array (afsnit 27.2), og at et array er en pointer til det første element i arrayet (afsnit 24.1).

En tekststreng opfattes i C som en pointer til det første tegn

Dette følger direkte af den generelle sammenhæng mellem arrays og pointere

Herunder, i program 27.3 ser vi et eksempel på et program, der tilgår tekststrenge via pointere. Overordnet set kopierer programmet tegnene i "Aalborg" ind midt i strengen str.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

int main(void) {
  char str_aal[] = "Aalborg";
  char str[14];

  char *str_1, *str_2;
  int i;

  /* fill str with '-' */
  for(i = 0; i < 14; i++)
    str[i] = '-';

  /* let str_1 and str_2 be running pointers */
  str_1 = str;  str_2 = str_aal;

  /* copy str_all into the middle of str */
  str_1 += 2;
  for( ; *str_2 != '\0'; str_1++, str_2++)
    *str_1 = *str_2;

  /* terminate str */
  *str_1 = '\0';

  printf("%s\n", str);  
  
  return 0;
}
Program 27.3    Et program der ved brug af pointere kopierer strengen "Aalborg" ind midt i en anden streng.

Lad os forklare programmet i lidt større detalje. I starten af main ser vi to variable str_all og str, som er strenge. Vi initialiserer str_all til "Aalborg". str initialiseres i den første forløkke til udelukkende at indeholde tegnene '-'.

Dernæst assignes str_1 og str_2 til pointere til de første tegn i hhv. str og str_all. Med rødt ser vi at str_1 føres to positioner frem i arrayet med '-' tegn. Dernæst kommer en forløkke, som kopierer tegnene i str_all over i str. Dette sker gennem de pointere vi har sat op til at gennemløbe disse arrays. Før vi udskriver str med printf indsætter vi eksplicit et '\0' tegn i str.

Herunder, i program 27.4 ser vi outputtet fra program 27.3.

1
--Aalborg
Program 27.4    Output fra programmet.

 

27.5.  Ændringer af tekststrenge
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Vi arbejder i dette afsnit videre på program 27.1. Det er vores mål at forklare under hvilke omstændigher vi kan ændre i de tekststrenge, som indgår i program 27.1.

Tekststrenge, til hvilke der er allokeret plads i et array, kan ændres (muteres)

Tekststrenge, der er angivet som en strengkonstant refereret af en pointer, kan ikke ændres

Mutation er et biologisk inspireret ord, som betyder at ændre (i en del af) noget. Ordet benyttes ofte når vi foretager ændringer i en del af en eksisterende datastruktur, eksempelvis et array.

Vores pointe bliver illustreret i program 27.5. Svarende til de farvede aspekter i program 27.1 foretager vi fire ændringer i strengen "Aalborg". Det er vigtigt at bide mærke i, at disse ændringer fortages i kommandoer, og sammen med erklæringerne af de benyttede variable.

Kun den lilla ændring giver problemer. str_3 peger på en tekststreng, der ikke er allokeret som et array i det program vi har skrevet. str_3 peger derimod på en konstant tekststreng, som er en del af programmet. Denne tekststreng er lagret sammen med programmet, på et sted vi ikke kan ændre i strengen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  char str_1[] = {'A', 'a', 'l', 'b', 'o', 'r', 'g', '\0'};
  *(str_1 + 1) = 'A';

  char str_2[8] = "Aalborg";
  *(str_2 + 1) = 'A';

  char *str_3 = "Aalborg";
  *(str_3 + 1) = 'A';  /* Fejl. Segmentation fault under kørsel */

  char str_4[8];
  str_4[0] = 'A';  str_4[1] = 'a';  str_4[2] = 'l';  
  str_4[3] = 'b';  str_4[4] = 'o';  str_4[5] = 'r';  
  str_4[6] = 'g';  str_4[7] = '\0';     
  *(str_4 + 1) = 'A';
Program 27.5    Et program der ændrer det andet tegn i Aalborg fra 'a' til 'A'.

Moralen vi kan uddrage af ovenstående er at mutation af en tekststreng kræver at denne tekststreng er allokeret statisk (afsnit 26.1) eller dynamisk (afsnit 26.2) i programmet. Vi kan ikke ændre i konstante tekststrenge, der er angivet som en del af programmet, og til hvilke vi har etableret en pointer.

 

27.6.  Tekststrenge i forhold til tegn
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Vi vil her påpege en væsentlig forskel mellem notationen for tegn og tekststrenge.

Tekststrenge er sammensat af tegn

De to værdier 'a' og "a" meget forskellige

Forskellen på notationen for tegn og tekststrenge kan eksemplificeres som følgende:

  • 'a'

    • Et enkelt tegn af typen char

    • Reelt heltallet 97

  • "a"

    • Et array med to elementer

    • Nulte element er tegnet 'a' og første element er tegnet '\0'

 

27.7.  Den tomme streng og NULL
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

I lighed for forskellen på 'a' og "a" vil vi nu pege på forskellen mellem NULL og den tomme tekststreng.

Man skal kunne skelne mellem den tomme tesktstreng og en NULL pointer

NULL og "" er meget forskellige

NULL og den tomme streng kan karakteriseres som følger:

  • NULL

    • NULL er en pointer værdi

    • NULL værdien bruges for en pointer, der ikke peger på en plads i lageret

    • Reelt heltallet 0

  • Den tomme streng ""

    • Den tomme string "" er en streng værdi

    • "" er et array med ét element, nemlig '\0' tegnet

Genereret: Onsdag 7. Juli 2010, 15:12:14
Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'