<<Pagina Materiale

 
 
 Siruri de caractere 
Definirea sirurilor de caractere

Limbajul C nu defineste tipul de data sir ( string in Pascal ), dar exista doua posibilitati de definire a sirurilor:

    • ca tablou de caractere; exemple:
      • char sir1[30];
      • char sir2[10]="exemplu";
    • ca pointer la caractere; exemple:
      • char *sir3; // sir3 trebuie initializat cu adresa unui  sir sau a unui spatiu alocat pe heap
          • sir3=sir1; // sir3 ia adresa unui sir static
                               // sir3=&sir1; sir3=&sir1[0]; sunt echivalente cu instr de atribuire de mai sus
          • sir3=(char *)malloc(100);// se aloca dinamic un spatiu pe heap
      • char *sir4="test";// sir2 este initializat cu adresa sirului constant
O constanta sir de caractere se reprezinta intre ghilimele.
Ultimul caracter din sir este caracterul nul ('\0'). Ex: "Anul 2001" ocupa 10 octeti de memorie, ultimul fiind '\0'.
Sus
Functii de prelucrare a sirurilor
  • declarate in stdio.h
    • char * gets(char * s);

    • citeste caracterele din intrare pina la intalnirea caracterului Enter, care nu se adauga la sirul s; plaseaza '\0' la sfarsitul lui s; returneaza adresa primului caracter din sir; daca se tasteaza CTRL/Z returneaza NULL; codul lui Enter e scos din buffer-ul de intrare
    • int puts(char * s);

    • tipareste sirul s, trece apoi la rand nou
    • scanf("%s",s);

    • citeste caracterele din intrare pina la intalnirea primului blanc sau Enter, care nu se adauga la sirul s; plaseaza '\0' la sfarsitul lui s; daca se tasteaza CTRL/Z returneaza EOF; codul lui blanc sau Enter raman in buffer-ul de intrare
    • printf("%s",s);

    • tipareste sirul s
  • declarate in string.h
    • int strcmp(char *s1,char *s2);

    • returneaza <0, daca s1 < s2
                 0, daca s1 = s2
               >0, daca s1 > s2
    • int strncmp(char *s1,char *s2,int n);

    • comparare a doua siruri pe lungimea n
    • char* strcpy(char *d,char *s);

    • copiaza sirul sursa s in sirul destinatie d; returneaza  adresa sirului destinatie
    • char* strncpy(char *d,char *s,int n);
             copiaza maxim n caractere de la sursa la destinatie; returneaza adresa sirului destinatie
    • int strlen(char *s);
             returneaza lungimea sirului fara a numara caracterul terminator
    • char* strcat(char *d,char *s);
             concateneaza cele doua siruri si returneaza adresa sirului rezultat
    • char* strchr(char s,char c);
             returneaza pozitia primei aparitii a caracterului c in sirul s, respectiv NULL daca c nu e in s
    • char* strstr(char *s,char *ss);
             returneaza pozitia primei aparitii a sirului ss in sirul s, respectiv NULL daca ss nu e in s.
    Sus
Quiz

Mai jos gasiti cateva autoteste prin care sa verificati intelegerea notiunilor de mai sus:

1.Care dintre secventele de mai jos copiaza sirul s1 in sirul s2?

char *s1="Curs online C/C++", *s2;

2.Exista vreun caracter care nu poate face parte dintr-un sir?

3.Ce se tipareste pe ecran?

#define L 15
char sir[L];
strcpy(sir,"123\0456");
printf("Sirul copiat este:/%s/ si are lungimea:%d\n",sir, strlen(sir));

Sus
Exercitii

1.Mai jos sunt prezentate variante de implementare a unor functii de biblioteca:
 

int strcmp( char *s1, char *s2){
   int i;
   for(i=0;s1[i]||s2[i];i++) 
      if(s1[i]<s2[i]) 
        return -1;
      else 
        if(s1[i]>s2[i])
          return 1;
   return 0;
  }
char *strcpy( char *d, char *s){
   int i=0;
   while(s[i]){ //0
     d[i]=s[i];i++;
   }
   d[i]='\0';   //1
   return d;
  }
//secventa ce cuprinde liniile dintre //0 si //1 inclusiv //este echivalenta cu:
       //while(d[i]=s[i])i++;
char *strcat(char *d, char *s){
    int i=0,j=0;
    while(d[i]) i++;
                 // la iesirea din while, i este indicele caracteruluiterminator
    while(d[i++]=s[j++]);
    return d;
  }

2.Sa se scrie un program care:

  • citeste cuvintele tastate fiecare pe cate un rand nou, pana la CTRL/Z  ( varianta: pana la introducerea unui cuvant vid )
  • afiseaza cuvantul cel mai lung
  • construieste si afiseaza cuvantul format din ultima litera din cuvintele introduse, transformata in minuscula ( nu vor fi prelucrate cuvintele ce nu se termina cu o litera )
  • afiseaza cuvintele ce incep cu o vocala.
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>

#define LUNG 81  // lungime maxima cuvant
#define NR 15 // nr max de cuvinte citite

char tab_cuv[NR][LUNG];
int nr_cuv=0;  // numarul cuvintelor introduse

void citire_cuv(void){
  printf("*** Se introduc maxim %d cuvinte, terminate cu CTRL/Z:\n",NR);
  while(nr_cuv<NR && gets(tab_cuv[nr_cuv]))nr_cuv++; 
      /* la CTRL/Z gets returneaza NULL (= 0) */
  /* citirea se poate face si cu scanf:
  while(nr_cuv<NR && scanf("%s",tab_cuv[nr_cuv])!=EOF)nr_cuv++; */
  /* daca terminarea se face cu un cuvant vid:
  while(nr_cuv<NR && strcmp("",gets(tab_cuv[nr_cuv])))nr_cuv++; */
}

/* Varianta: tab_cuv se declara ca tablou de pointeri, se modifica declaratia lui tab_cuv si functia citire_cuv, restul functiilor raman nemodificate;

#include <alloc.h>
char* tab_cuv[NR];
void citire_cuv(void){
  char cuv_crt[LUNG];
  printf("*** Se introduc maxim %d cuvinte, terminate cu CTRL/Z:\n",NR);
  while(nr_cuv<NR && gets(cuv_crt)){
    if((tab_cuv[nr_cuv]=(char *)malloc(strlen(cuv_crt)+1))==NULL){
      puts("*** Spatiu insuficient ! ***");
      exit(1);
    }
    strcpy(tab_cuv[nr_cuv],cuv_crt);
    nr_cuv++; 
  }
}
*/

void constr_cuv(void){
  char c,cuv[NR+1]; /* lungimea maxima este egala cu numarul maxim de cuvinte + 1 pentru terminator */
  int i,j,lung; /* i parcurge cuvintele din tab_cuv, j pozitiile din cuv, lung e lungimea cuv curent */
  for(i=j=0;i<nr_cuv;i++)
    if((lung=strlen(tab_cuv[i]))>0 && isalpha(c=tolower(tab_cuv[i][lung-1])))
      cuv[j++]=c;
  cuv[j]='\0';
  printf("*** Cuvantul construit:|%s|\n",cuv);
}

void cuv_max(void){
  int i,lung_crt,lung_max=0; 
  char * p_max; /* pointerul spre cuvantul maxim */
    /* se poate memora indicele cuvantului maxim: int i_max;
       sau memora cuvantul maxim intr-un sir: char c_max[LUNG]; */
  for(i=0;i<nr_cuv;i++)
    if((lung_crt=strlen(tab_cuv[i]))>lung_max){
      p_max=tab_cuv[i];
      lung_max=lung_crt;
    }
  printf("*** Cuvantul de lungime maxima %d este:|%s|\n",lung_max,p_max);
}

void cuv_vocale(void){
  int i;
  puts("*** Cuvintele ce incep cu vocale:");
  for(i=0;i<nr_cuv;i++)
    switch(toupper(tab_cuv[i][0])){
     case 'A': case'E': case 'I': case 'O': case 'U':puts(tab_cuv[i]);
   }  /* in loc de switch se putea folosi
  char c; if(c=toupper(tab_cuv[i][0]),c=='A' ||
     c=='E' || ...)puts(tab_cuv[i]); */
}

void main(void){

  citire_cuv();
  cuv_max();
  constr_cuv();
  cuv_vocale();

  getch();

Adaugati prelucrarile pentru ca programul sa mai afiseze: 
- cuvintele in ordine alfabetica - se va modifica functia de ordonare a unui tablou de intregi 
- cuvantul ce contine numarul maxim de vocale, respectiv consoane 
- cuvintele ce sunt reprezentarea unor numere intregi sau reale 
- cuvintele inversate 
- cuvintele care sunt palindroame - un palindrom este un cuvant identic cu inversatul sau. 

3.Se citesc trei siruri s1, s2 si s3. Sa se afiseze sirul obtinut prin inlocuirea in s1 a tuturor aparitiilor lui s2 prin s3. ( Observatie: Daca s3 este sirul vid, din s1 se vor sterge toate subsirurile s2 ).
 

#include <stdio.h>
#include <string.h>

#define LUNGS 81

void main(void){
  char s1[LUNGS],s2[LUNGS],s3[LUNGS],rezultat[LUNGS];
  char *s1ptr=s1,*s2pos, *rezptr=rezultat;

  puts("*** sirul s1:"); gets(s1);
  puts("*** subsirul s2:"); gets(s2);
  puts("*** s3:"); gets(s3);

  while(s2pos=strstr(s1ptr,s2)){ 
    while(s1ptr<s2pos)*rezptr++=*s1ptr++;
    strcpy(rezptr,s3);
    rezptr+=strlen(s3);
    s1ptr+=strlen(s2);
  }
  strcpy(rezptr,s1ptr);
  puts("*** sirul rezultat:"); puts(rezultat);

  getch();

4. Pornind de la un sir citit de la tastatura, sa se construiasca si sa se tipareasca ( ultimele trei prelucrari nu sunt implementate ):

  • sirul care contine cifrele din cel initial
  • sirul care contine minusculele vocalelor din cel initial
  • sirul invers celui initial; sa se verifice daca sirul initial este palindrom
  • sirul care contine majusculele literelor din cel initial 
  • sirul care contine m caractere incepand de la pozitia p din sirul initial; m si p se citesc 
  • sirul care contine caracterele celui initial cu exceptia celor m incepand de la pozitia p; m si p se citesc.
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>

#define LUNGS 81

//variabile globale
char sir[LUNGS],aux[LUNGS];//sirul citit si cel in care se fac prelucrarile

//prototipuri
void constr1(void);
void constr2(void);
void constr3(void);

//definire main
void main(void){

  clrscr();
  puts("*** sirul de prelucrat:"); gets(sir);

  constr1();
  constr2();
  constr3();

  getch();
}//main 

//definire functii
void constr1(void){
  int i,j; //i indice in sir, j in aux
  for (i=j=0;i<strlen(sir);i++) // expresia conditie poate fi sir[i]
    if(isdigit(sir[i])) // conditia echivalenta cu '0'<=sir[i]<='9'
      aux[j++]=sir[i];
  aux[j]='\0';
  printf("Sirul de cifre:%s\n",aux);
}

void constr2(void){
  int i,j; 
  char c;
  for (i=j=0;i<strlen(sir);i++) 
    if(c=tolower(sir[i]),c=='a'||c=='e'||c=='i'||c=='o'||c=='u')
      aux[j++]=c;
  aux[j]='\0'; 
  printf("Sirul de vocale:%s\n",aux);
}

void constr3(void){
  int i,lung; //lung ia valoarea lungimii sirului
  for (i=0,lung=strlen(sir);i<lung;i++) 
    aux[i]=sir[lung-1-i];
  aux[i]='\0'; 
  printf("Sirul invers:%s\n",aux);

  //verificare daca sirul initial este palindrom <=> identic cu inversul sau
  if(strcmp(sir,aux)==0)
    puts("*** Este palindrom");
  else
    puts("*** Nu este palindrom");
}

5.Sa se citeasca si sa se tipareasca o matrice de siruri. Sa se gaseasca sirul din matrice care are numarul maxim de consoane. 

Sus
<<Pagina Materiale


Copyright © 2001-2002. Carmen Holotescu
All rights reserved. Published by Timsoft